!11 follow后端发布
* docs: readme * fix: missing formPath * chore: 去除锁定的esbuild版本 * perf: 去除debug组件 * perf: 参数键值 自动高度 * refactor: 代码生成配置页面重构 去除步骤条 * perf: 移除文件 * docs: 文件夹说明 * chore: 移除一些配置项 * chore: 注释优化 * refactor: 移除ele和naive目录 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * perf: request support to set how to return response (#5436) * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * refactor: 登录超时的i18n * fix: requestClient缺失i18n内容 * refactor: 优化oss下载进度提示 * feat: 下载进度loading * fix: antd button icon style (#5421) * feat: oss下载进度(已下载的KB 无法作为进度显示 total返回为null) * fix: 下载文件时(responseType === 'blob')需要判断下载失败(返回json而非二进制)的情况 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * refactor: 新增后跳转到未发布流程 * fix: same name route * chore: 调整为部署json类型 * fix: mouse events ignored on modal loading (#5409) * docs: update docs (#5408) * refactor: 移除已经弃用的方法 * refactor: follow官方handleRangeTimeValue更新 * chore: 删除文件夹(前端路由需要的) * chore: 修改本地路由写法(新版)/新增本地菜单图标 * fix: form update state error before form mounted (#5406) * fix: demos route fixed (#5405) * chore: 不使用基础布局(仅在顶级生效) * feat: modal state locked on submitting (#5401) * chore: 修改zIndex * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * refactor: fix popup component zIndex (#5397) * style: element plus loading style fixed (#5393) * perf: improve fieldMappingTime to support format function (#5392) * fix: hide root route in breadcrumb * feat: support set default props for drawer and modal (#5390) * fix: root router config fixed (#5389) * fix: 修改Vxe默认zIndex为995 解决右上角全屏后modal/drawer(zIndex: 1000)被遮挡 * feat: add `noBasicLayout` in route meta (#5386) * chore: wechat image * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * chore: 改为全局参数配置 去除局部参数 * fix: spinner may stop playing animation after dismiss (#5365) * style: popover bgColor is too close to common (#5364) * docs: version update * docs: changelog * chore: 文件上传 描述 * ci: retry deploy while faild * feat: 文件上传 进度条+提示文字 * feat: 文件上传 进度条 * feat: 上传文件格式说明 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into warmflow * fix: useEcharts return invalid instance (#5360) * feat: popup component support overlay blur effect (#5359) * feat: improve `tippy` demo (#5357) * feat: integrate new component `Tippy` with demo (#5355) * chore: 优化表格图片显示 * perf: add nested modal demo (#5353) * chore: 默认显示右边的滚动条 防止出现滚动条被挤压 * perf: modal and drawer api support chain calls (#5351) * feat: allow close tab when mouse middle button click (#5347) * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into warmflow * refactor: 重构显示total的逻辑 * chore: 调整高度自适应代码 * chore: vxe升级4.10.0版本(锁定) * fix: 添加失效的option * fix: 需要为数组 * fix: locale switching logic correction (#5344) * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into warmflow * chore: 导入类型优化 解决eslint报红 * refactor: type/注释优化 去除大量any * fix: vxeGrid init without search form (#5342) * chore: 锁屏默认false 关闭该功能 * chore: 调整接口 * chore: update deps * fix: primaryColor calculation (#5337) * fix: form valid-error style in naive (#5336) * fix: form `fieldMappingTime` improve and `modelPropName` support (#5335) * fix: code lint * fix: form `fieldMappingTime` is not working (#5333) * chore: 选人组件样式 * fix: download from url triggered twice sometimes (#5319) * chore: 优化代码 * chore: 动态类名(无效)改为style * refactor: 字典相关功能重构 采用一个Map储存字典(之前为两个Map) * feat: 字典支持number类型存储 * chore: 调整样式 * chore: 修改选中border为1px * chore: 字段 * chore: 改为新窗口打开(适用于pdf/图片)而非直接下载 * chore: 更新样式 * chore: 更新字段 * chore: 改为computed * chore: 跳转到未发布流程tab * chore: 优化样式 * docs: readme * fix: name重复导致的404 * Merge branch 'dev' of https://gitee.com/dapppp/ruoyi-plus-vben5 into warmflow * chore: 使用legacy来保证copy的兼容性 * chore: 去除log 添加说明 * chore: 优化代码 * feat: 节点关联/节点独立的切换逻辑 * chore: remove logic * chore: vxe可编辑表格demo * chore: 不允许在按钮下添加数据 * docs: changelog * fix: wrong code * chore: 移除测试菜单 * chore: 优化代码 * refactor: 租户套餐菜单替换为新版 * refactor: 使用新版菜单勾选 * chore: 点行会勾选/取消全部权限 点权限不会勾选行 * chore: 全屏引导+样式优化 * chore: 调整间距 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * feat: useEcharts exports echarts instance#5294 (#5299) * chore: update quick-start.md (#5303) * chore: updateCheckedNumber * refactor: 优化代码 * chore: 优化代码 * chore: 优化样式 * chore: keys依赖于menu 需要先加载menu * chore: 菜单加载完毕再显示 * feat: 新的菜单选择组件(beta) * chore: $t * chore: 测试菜单页面 * chore: 优化代码 * feat: 对ossId回显的支持 * chore: 只获取一次默认密码而非每次打开modal都获取 * fix: vben select placeholder color (#5286) * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * perf: format code with better style (#5283) * chore: 工作流演示站 * fix: sidebar preferences fixed (#5276) * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * fix: breadcrumb setting not valid for `header-sidebar-nav` layout (#5275) * fix: header logo may not be collapsed in `header-sidebar-nav` layout (#5274) * feat: new layout `sidebar nav with full header` (#5270) * feat: drawer close icon placement (#5269) * docs: update dialog and drawer docs * feat: drawer support destroy on close * feat: drawer support `onOpened` & `onClosed` * feat: modal support destroy on close * fix: wrong boolean * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * chore: 调整tab位置 * chore: 删除历史流程 改为tab切换 * fix: header-mixed layout side-menu active (#5265) * feat: header mixed layout (#5263) * chore: release 5.5.2 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * chore: downgrade vue-tsc version * feat: header menu align support (#5256) * chore: update deps * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * chore: add apiSelect remote search demo (#5246) * chore: 审批改为description而非disabled的表单 * chore: 改为ts * chore: 错误的conetnt * refactor: 终止/转办/委托支持填写意见 * chore: 第一次拿到的是readonly的数据 如果需要修改 需要cloneDeep * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * fix: grid form submit button locale switch (#5205) * chore: 调整驳回 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * fix: build error (#5199) * fix: esbuild自动升级导致运行/打包报错 * fix: esbuild自动升级导致运行/打包报错 * chore: 流程定义 激活改为switch * chore: 流程申请支持上传文件 * chore: title 审批通过 * fix: vxeGrid top padding (#5193) * fix: 表格排序翻页会丢失排序参数 * chore: 去除log打印 * chore: 流程监控 待办任务 * chore: 我发起的 * chore: 去除已经移除的菜单页面 * chore: 我的已办 * chore: 页面优化 * chore: 重置tooltip * feat: 我的抄送搜索/优化重复触发的接口 * feat: 流程定义 历史 * chore: 修改分类 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * fix: grid tools in toolbar config not working as expected (#5190) * feat: add `resizable` and `ColPage` component (#5188) * chore: 条件 * chore: break-all * feat: 流程分类 搜索 * chore: 弹窗关闭后仍然显示表单浮层 * chore: 选人组件的样式 * chore: 搜索的样式 * chore: 漏掉的导入 * chore: 最大显示的头像数量 超过显示为省略号头像 * fix: 选人的一些问题 * Merge branch 'warmflow' of https://gitee.com/dapppp/ruoyi-plus-vben5 i… * chore: 没有更多数据了 * fix: sidebar header height (#5183) * chore: 搜索表单布局+申请人 * fix: remove the overlap caused by border-b (#5160) * docs: fix typos (#5169) * fix: resolve eslint errors as well as TS type errors (#5172) * chore: enter提交表单 * chore: 修改文案 * chore: 默认全部展开 * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * feat: page content class override (#5179) * fix: sidebar style on focus (#5178) * fix: 抄送选人 最右侧已选中删除item无效 * feat: 复制 * chore: 昵称过长的显示 * chore: 默认选中第一个 * chore: 修改relative位置 * chore: 搜索 * feat: 我的待办 - 搜索条件 * chore: 流程监控 - 待办任务页面的id不唯一 改为前端处理 * feat: 修改办理人 * chore: 流程干预 - 加签/减签 * chore: avatar大小 * chore: 抄送需要手动添加createByName * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * chore: 审批通过 抄送 * feat: 流程实例-流程预览 * chore: spell * chore: clientid * chore: 分类条件 * chore: 修改办理人 * chore: 更改postMessage参数 * chore: 内嵌iframe高度根据表单高度调整 * chore: 流程详情 * feat: 抄送选择 * chore: 调整分类树 * fix: user homePath no effect sometimes (#5166) * feat: form compact mode support (#5165) * fix: form auto submit no effect when showDefaultActions is false (#5163) * chore: 修改width * feat: 待办任务 * feat: 我的抄送 * chore: 流程定义 样式 * chore: 退回后重新申请 * chore: 请假申请布局 * chore: 请假申请-并行会签网关 * chore: 分类去除根目录 * chore: 详情modal(未完成) * chore: 请假申请根据不同状态显示按钮 * chore: 流程删除/撤销 * chore: 审批完成后刷新当前页 * feat: 选人组件(未完成) 加签减签 * docs: fix docs-link and add `EllipsisText` docs (#5158) * chore: 新窗口打开文件 * chore: 审批通过 * chore: 使用useEventListener替换原生 * chore: 字段错误 * chore: iframe通信 加载完毕后才显示表单 解决卡顿问题 * chore: 审批终止/驳回 * chore: 附件图标 * chore: process_running显示按钮 * chore: label错误 * chore: 保存的事件 * chore: 需要加上clientId * Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev * feat: form `colon` support (#5156) * chore: 完善请假申请 * feat: improve code login demo (#5154) * chore: 客户端管理 行高自适应 * chore: 内嵌表单的路径 * chore: 修改avatar背景色 * chore: 注释 * chore: activePath * chore: leave表单 * chore: 修改请假demo路径 * chore: categoryId * chore: 我的已办 * chore: 我发起的 * chore: loading * chore: 历史版本 * chore: 完善task api * chore: 隐藏'菜单加载中' * chore: missing import * feat: add demo for modify menu badge data * chore: 流程实例 * chore: 审批附件 * chore: 我的待办 提取公共组件 * chore: 流程部署 * chore: 新增/编辑/导出xml * chore: 流程定义(除历史版本) * feat: `autoActivateChild` support more layout mode (#5148) * feat: auto activate subMenu on select root menu (#5147) * fix: `disabledOnChangeListener` not work in form (#5146) * fix: login expired modal z-index (#5145) * feat: user-dropdown support `hover` trigger (#5143) * fix: pinInput value synchronous update (#5142) * fix: vxeGrid default sort data no effect in first query (#5141) * fix: vscode debug profile (#5140) * fix: form component events bind (#5137) * chore: 在线用户样式 开启虚拟滚动 * chore: 去掉个人中心 在线设备的分页 * chore: 去掉在线用户的分页 * chore: changelog * refactor: 获取字典的方法 提取公共函数 减少冗余代码 * fix: element plus validate failed style (#5130) * chore: 使用私有桶的提示 * feat: tabbar support mouse wheel vertical (#5129) * fix: form support `disabledOnInputListener` (#5127) * fix: form submission not appropriate (#5126) * Merge branch 'main' of https://gitee.com/dapppp/ruoyi-plus-vben5 into dev * chore: release 5.5.1 * feat: table search form visible control (#5121) * chore: 需要隐藏菜单 * chore: 我的待办 & 请假 * chore: 流程定义(未完成) * chore: 流程定义(开发中) * Merge branch 'main' of https://gitee.com/dapppp/ruoyi-plus-vben5 into dev * Merge branch 'main' of https://gitee.com/dapppp/ruoyi-plus-vben5 into dev * Merge branch 'main' of https://gitee.com/dapppp/ruoyi-plus-vben5 into dev * chore: version * chore: 锁定vxe-table版本 4.9.8版本存在样式问题 * chore: 暂时锁定cspell版本 * refactor: 由于不能输入 需要使用watch监听 * chore: https://gitee.com/dapppp/ruoyi-plus-vben5/issues/IB7ANL * chore: 移除冗余代码 * chore: 组件卸载时移除emitter * fix: the route path did not synchronize with the page (#4947) * style: typo (#4948) * chore: 替换为commonDownloadExcel * fix: 左边部门树错误emit导致会调用两次列表api * chore: label样式 * chore: 改为Textarea * chore: 滚动条宽度 * chore: 审批样式 * chore: 部门及以下或本人数据权限 * Merge branch 'main' of https://gitee.com/dapppp/ruoyi-plus-vben5 into dev * chore: 个人中心强退设备接口路径
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import type { Component } from 'vue';
|
||||
|
||||
import type { AnyPromiseFunction } from '@vben/types';
|
||||
|
||||
import { type Component, computed, ref, unref, useAttrs, watch } from 'vue';
|
||||
import { computed, ref, unref, useAttrs, watch } from 'vue';
|
||||
|
||||
import { LoaderCircle } from '@vben/icons';
|
||||
|
||||
import { get, isEqual, isFunction } from '@vben-core/shared/utils';
|
||||
|
||||
import { objectOmit } from '@vueuse/core';
|
||||
@@ -118,7 +121,7 @@ const bindProps = computed(() => {
|
||||
[`onUpdate:${props.modelPropName}`]: (val: string) => {
|
||||
modelValue.value = val;
|
||||
},
|
||||
...objectOmit(attrs, ['onUpdate:value']),
|
||||
...objectOmit(attrs, [`onUpdate:${props.modelPropName}`]),
|
||||
...(props.visibleEvent
|
||||
? {
|
||||
[props.visibleEvent]: handleFetchForVisible,
|
||||
@@ -188,18 +191,16 @@ function emitChange() {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div v-bind="{ ...$attrs }">
|
||||
<component
|
||||
:is="component"
|
||||
v-bind="bindProps"
|
||||
:placeholder="$attrs.placeholder"
|
||||
>
|
||||
<template v-for="item in Object.keys($slots)" #[item]="data">
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
<template v-if="loadingSlot && loading" #[loadingSlot]>
|
||||
<LoaderCircle class="animate-spin" />
|
||||
</template>
|
||||
</component>
|
||||
</div>
|
||||
<component
|
||||
:is="component"
|
||||
v-bind="bindProps"
|
||||
:placeholder="$attrs.placeholder"
|
||||
>
|
||||
<template v-for="item in Object.keys($slots)" #[item]="data">
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
<template v-if="loadingSlot && loading" #[loadingSlot]>
|
||||
<LoaderCircle class="animate-spin" />
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
@@ -1,8 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { PointSelectionCaptchaCardProps } from '../types';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import {
|
||||
Card,
|
||||
@@ -11,6 +9,7 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = withDefaults(defineProps<PointSelectionCaptchaCardProps>(), {
|
||||
height: '220px',
|
||||
|
@@ -5,12 +5,10 @@ import type {
|
||||
SliderRotateVerifyPassingData,
|
||||
} from '../types';
|
||||
|
||||
import { reactive, unref, useTemplateRef, watch, watchEffect } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
import { useTimeoutFn } from '@vueuse/core';
|
||||
import { reactive, unref, useTemplateRef, watch, watchEffect } from 'vue';
|
||||
|
||||
import SliderCaptchaAction from './slider-captcha-action.vue';
|
||||
import SliderCaptchaBar from './slider-captcha-bar.vue';
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { computed, ref, useTemplateRef } from 'vue';
|
||||
|
||||
import { Check, ChevronsRight } from '@vben/icons';
|
||||
import { Slot } from '@vben-core/shadcn-ui';
|
||||
import { computed, ref, useTemplateRef } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
actionStyle: CSSProperties;
|
||||
|
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, type CSSProperties, ref, useTemplateRef } from 'vue';
|
||||
import type { CSSProperties } from 'vue';
|
||||
|
||||
import { computed, ref, useTemplateRef } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
barStyle: CSSProperties;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { computed, useTemplateRef } from 'vue';
|
||||
|
||||
import { VbenSpineText } from '@vben-core/shadcn-ui';
|
||||
import { computed, useTemplateRef } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
contentStyle: CSSProperties;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import type { ClassType } from '@vben/types';
|
||||
|
||||
import type { CSSProperties } from 'vue';
|
||||
|
||||
export interface CaptchaData {
|
||||
|
107
packages/effects/common-ui/src/components/col-page/col-page.vue
Normal file
107
packages/effects/common-ui/src/components/col-page/col-page.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<script lang="ts" setup>
|
||||
import type { ColPageProps } from './types';
|
||||
|
||||
import { computed, ref, useSlots } from 'vue';
|
||||
|
||||
import {
|
||||
ResizableHandle,
|
||||
ResizablePanel,
|
||||
ResizablePanelGroup,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
import Page from '../page/page.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'ColPage',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<ColPageProps>(), {
|
||||
leftWidth: 30,
|
||||
rightWidth: 70,
|
||||
resizable: true,
|
||||
});
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { leftWidth: _, ...delegated } = props;
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const slots = useSlots();
|
||||
|
||||
const delegatedSlots = computed(() => {
|
||||
const resultSlots: string[] = [];
|
||||
|
||||
for (const key of Object.keys(slots)) {
|
||||
if (!['default', 'left'].includes(key)) {
|
||||
resultSlots.push(key);
|
||||
}
|
||||
}
|
||||
return resultSlots;
|
||||
});
|
||||
|
||||
const leftPanelRef = ref<InstanceType<typeof ResizablePanel>>();
|
||||
|
||||
function expandLeft() {
|
||||
leftPanelRef.value?.expand();
|
||||
}
|
||||
|
||||
function collapseLeft() {
|
||||
leftPanelRef.value?.collapse();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
expandLeft,
|
||||
collapseLeft,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Page v-bind="delegatedProps">
|
||||
<!-- 继承默认的slot -->
|
||||
<template
|
||||
v-for="slotName in delegatedSlots"
|
||||
:key="slotName"
|
||||
#[slotName]="slotProps"
|
||||
>
|
||||
<slot :name="slotName" v-bind="slotProps"></slot>
|
||||
</template>
|
||||
|
||||
<ResizablePanelGroup class="w-full" direction="horizontal">
|
||||
<ResizablePanel
|
||||
ref="leftPanelRef"
|
||||
:collapsed-size="leftCollapsedWidth"
|
||||
:collapsible="leftCollapsible"
|
||||
:default-size="leftWidth"
|
||||
:max-size="leftMaxWidth"
|
||||
:min-size="leftMinWidth"
|
||||
>
|
||||
<template #default="slotProps">
|
||||
<slot
|
||||
name="left"
|
||||
v-bind="{
|
||||
...slotProps,
|
||||
expand: expandLeft,
|
||||
collapse: collapseLeft,
|
||||
}"
|
||||
></slot>
|
||||
</template>
|
||||
</ResizablePanel>
|
||||
<ResizableHandle
|
||||
v-if="resizable"
|
||||
:style="{ backgroundColor: splitLine ? undefined : 'transparent' }"
|
||||
:with-handle="splitHandle"
|
||||
/>
|
||||
<ResizablePanel
|
||||
:collapsed-size="rightCollapsedWidth"
|
||||
:collapsible="rightCollapsible"
|
||||
:default-size="rightWidth"
|
||||
:max-size="rightMaxWidth"
|
||||
:min-size="rightMinWidth"
|
||||
>
|
||||
<template #default>
|
||||
<slot></slot>
|
||||
</template>
|
||||
</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
</Page>
|
||||
</template>
|
@@ -0,0 +1,2 @@
|
||||
export { default as ColPage } from './col-page.vue';
|
||||
export * from './types';
|
26
packages/effects/common-ui/src/components/col-page/types.ts
Normal file
26
packages/effects/common-ui/src/components/col-page/types.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { PageProps } from '../page/types';
|
||||
|
||||
export interface ColPageProps extends PageProps {
|
||||
/**
|
||||
* 左侧宽度
|
||||
* @default 30
|
||||
*/
|
||||
leftWidth?: number;
|
||||
leftMinWidth?: number;
|
||||
leftMaxWidth?: number;
|
||||
leftCollapsedWidth?: number;
|
||||
leftCollapsible?: boolean;
|
||||
/**
|
||||
* 右侧宽度
|
||||
* @default 70
|
||||
*/
|
||||
rightWidth?: number;
|
||||
rightMinWidth?: number;
|
||||
rightCollapsedWidth?: number;
|
||||
rightMaxWidth?: number;
|
||||
rightCollapsible?: boolean;
|
||||
|
||||
resizable?: boolean;
|
||||
splitLine?: boolean;
|
||||
splitHandle?: boolean;
|
||||
}
|
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, type CSSProperties, ref, watchEffect } from 'vue';
|
||||
import type { CSSProperties } from 'vue';
|
||||
|
||||
import { VbenTooltip } from '@vben-core/shadcn-ui';
|
||||
import { computed, ref, watchEffect } from 'vue';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, h, ref, type VNode, watch, watchEffect } from 'vue';
|
||||
import type { VNode } from 'vue';
|
||||
|
||||
import { usePagination } from '@vben/hooks';
|
||||
import { EmptyIcon, Grip, listIcons } from '@vben/icons';
|
||||
@@ -18,8 +18,8 @@ import {
|
||||
VbenIconButton,
|
||||
VbenPopover,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
import { refDebounced } from '@vueuse/core';
|
||||
import { computed, h, ref, watch, watchEffect } from 'vue';
|
||||
|
||||
interface Props {
|
||||
pageSize?: number;
|
||||
|
@@ -1,12 +1,14 @@
|
||||
export * from './api-component';
|
||||
export * from './captcha';
|
||||
export * from './code-mirror';
|
||||
export * from './col-page';
|
||||
export * from './ellipsis-text';
|
||||
export * from './icon-picker';
|
||||
export * from './json-preview';
|
||||
export * from './markdown';
|
||||
export * from './page';
|
||||
export * from './resize';
|
||||
export * from './tippy';
|
||||
export * from '@vben-core/form-ui';
|
||||
export * from '@vben-core/popup-ui';
|
||||
|
||||
|
@@ -1 +1,2 @@
|
||||
export { default as Page } from './page.vue';
|
||||
export * from './types';
|
||||
|
@@ -1,33 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
onMounted,
|
||||
ref,
|
||||
type StyleValue,
|
||||
useTemplateRef,
|
||||
} from 'vue';
|
||||
import type { StyleValue } from 'vue';
|
||||
|
||||
import type { PageProps } from './types';
|
||||
|
||||
import { CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT } from '@vben-core/shared/constants';
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
description?: string;
|
||||
contentClass?: string;
|
||||
/**
|
||||
* 根据content可见高度自适应
|
||||
*/
|
||||
autoContentHeight?: boolean;
|
||||
headerClass?: string;
|
||||
footerClass?: string;
|
||||
}
|
||||
import { computed, nextTick, onMounted, ref, useTemplateRef } from 'vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'Page',
|
||||
});
|
||||
|
||||
const { autoContentHeight = false } = defineProps<Props>();
|
||||
const { autoContentHeight = false } = defineProps<PageProps>();
|
||||
|
||||
const headerHeight = ref(0);
|
||||
const footerHeight = ref(0);
|
||||
@@ -100,7 +84,7 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="contentClass" :style="contentStyle" class="h-full p-4">
|
||||
<div :class="cn('h-full p-4', contentClass)" :style="contentStyle">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
|
11
packages/effects/common-ui/src/components/page/types.ts
Normal file
11
packages/effects/common-ui/src/components/page/types.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export interface PageProps {
|
||||
title?: string;
|
||||
description?: string;
|
||||
contentClass?: string;
|
||||
/**
|
||||
* 根据content可见高度自适应
|
||||
*/
|
||||
autoContentHeight?: boolean;
|
||||
headerClass?: string;
|
||||
footerClass?: string;
|
||||
}
|
100
packages/effects/common-ui/src/components/tippy/directive.ts
Normal file
100
packages/effects/common-ui/src/components/tippy/directive.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import type { ComputedRef, Directive } from 'vue';
|
||||
|
||||
import { useTippy } from 'vue-tippy';
|
||||
|
||||
export default function useTippyDirective(isDark: ComputedRef<boolean>) {
|
||||
const directive: Directive = {
|
||||
mounted(el, binding, vnode) {
|
||||
const opts =
|
||||
typeof binding.value === 'string'
|
||||
? { content: binding.value }
|
||||
: binding.value || {};
|
||||
|
||||
const modifiers = Object.keys(binding.modifiers || {});
|
||||
const placement = modifiers.find((modifier) => modifier !== 'arrow');
|
||||
const withArrow = modifiers.includes('arrow');
|
||||
|
||||
if (placement) {
|
||||
opts.placement = opts.placement || placement;
|
||||
}
|
||||
|
||||
if (withArrow) {
|
||||
opts.arrow = opts.arrow === undefined ? true : opts.arrow;
|
||||
}
|
||||
|
||||
if (vnode.props && vnode.props.onTippyShow) {
|
||||
opts.onShow = function (...args: any[]) {
|
||||
return vnode.props?.onTippyShow(...args);
|
||||
};
|
||||
}
|
||||
|
||||
if (vnode.props && vnode.props.onTippyShown) {
|
||||
opts.onShown = function (...args: any[]) {
|
||||
return vnode.props?.onTippyShown(...args);
|
||||
};
|
||||
}
|
||||
|
||||
if (vnode.props && vnode.props.onTippyHidden) {
|
||||
opts.onHidden = function (...args: any[]) {
|
||||
return vnode.props?.onTippyHidden(...args);
|
||||
};
|
||||
}
|
||||
|
||||
if (vnode.props && vnode.props.onTippyHide) {
|
||||
opts.onHide = function (...args: any[]) {
|
||||
return vnode.props?.onTippyHide(...args);
|
||||
};
|
||||
}
|
||||
|
||||
if (vnode.props && vnode.props.onTippyMount) {
|
||||
opts.onMount = function (...args: any[]) {
|
||||
return vnode.props?.onTippyMount(...args);
|
||||
};
|
||||
}
|
||||
|
||||
if (el.getAttribute('title') && !opts.content) {
|
||||
opts.content = el.getAttribute('title');
|
||||
el.removeAttribute('title');
|
||||
}
|
||||
|
||||
if (el.getAttribute('content') && !opts.content) {
|
||||
opts.content = el.getAttribute('content');
|
||||
}
|
||||
|
||||
useTippy(el, opts);
|
||||
},
|
||||
unmounted(el) {
|
||||
if (el.$tippy) {
|
||||
el.$tippy.destroy();
|
||||
} else if (el._tippy) {
|
||||
el._tippy.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
updated(el, binding) {
|
||||
const opts =
|
||||
typeof binding.value === 'string'
|
||||
? { content: binding.value, theme: isDark.value ? '' : 'light' }
|
||||
: Object.assign(
|
||||
{ theme: isDark.value ? '' : 'light' },
|
||||
binding.value,
|
||||
);
|
||||
|
||||
if (el.getAttribute('title') && !opts.content) {
|
||||
opts.content = el.getAttribute('title');
|
||||
el.removeAttribute('title');
|
||||
}
|
||||
|
||||
if (el.getAttribute('content') && !opts.content) {
|
||||
opts.content = el.getAttribute('content');
|
||||
}
|
||||
|
||||
if (el.$tippy) {
|
||||
el.$tippy.setProps(opts || {});
|
||||
} else if (el._tippy) {
|
||||
el._tippy.setProps(opts || {});
|
||||
}
|
||||
},
|
||||
};
|
||||
return directive;
|
||||
}
|
67
packages/effects/common-ui/src/components/tippy/index.ts
Normal file
67
packages/effects/common-ui/src/components/tippy/index.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { DefaultProps, Props } from 'tippy.js';
|
||||
|
||||
import type { App, SetupContext } from 'vue';
|
||||
|
||||
import { h, watchEffect } from 'vue';
|
||||
import { setDefaultProps, Tippy as TippyComponent } from 'vue-tippy';
|
||||
|
||||
import { usePreferences } from '@vben-core/preferences';
|
||||
|
||||
import useTippyDirective from './directive';
|
||||
|
||||
import 'tippy.js/dist/tippy.css';
|
||||
import 'tippy.js/dist/backdrop.css';
|
||||
import 'tippy.js/themes/light.css';
|
||||
import 'tippy.js/animations/scale.css';
|
||||
import 'tippy.js/animations/shift-toward.css';
|
||||
import 'tippy.js/animations/shift-away.css';
|
||||
import 'tippy.js/animations/perspective.css';
|
||||
|
||||
const { isDark } = usePreferences();
|
||||
export type TippyProps = Partial<
|
||||
Props & {
|
||||
animation?:
|
||||
| 'fade'
|
||||
| 'perspective'
|
||||
| 'scale'
|
||||
| 'shift-away'
|
||||
| 'shift-toward'
|
||||
| boolean;
|
||||
theme?: 'auto' | 'dark' | 'light';
|
||||
}
|
||||
>;
|
||||
|
||||
export function initTippy(app: App<Element>, options?: DefaultProps) {
|
||||
setDefaultProps({
|
||||
allowHTML: true,
|
||||
delay: [500, 200],
|
||||
theme: isDark.value ? '' : 'light',
|
||||
...options,
|
||||
});
|
||||
if (!options || !Reflect.has(options, 'theme') || options.theme === 'auto') {
|
||||
watchEffect(() => {
|
||||
setDefaultProps({ theme: isDark.value ? '' : 'light' });
|
||||
});
|
||||
}
|
||||
|
||||
app.directive('tippy', useTippyDirective(isDark));
|
||||
}
|
||||
|
||||
export const Tippy = (props: any, { attrs, slots }: SetupContext) => {
|
||||
let theme: string = (attrs.theme as string) ?? 'auto';
|
||||
if (theme === 'auto') {
|
||||
theme = isDark.value ? '' : 'light';
|
||||
}
|
||||
if (theme === 'dark') {
|
||||
theme = '';
|
||||
}
|
||||
return h(
|
||||
TippyComponent,
|
||||
{
|
||||
...props,
|
||||
...attrs,
|
||||
theme,
|
||||
},
|
||||
slots,
|
||||
);
|
||||
};
|
@@ -1,2 +1,3 @@
|
||||
export * from './components';
|
||||
export * from './ui';
|
||||
export { VbenAvatar } from '@vben-core/shadcn-ui';
|
||||
|
@@ -1,14 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import type { AboutProps, DescriptionItem } from './about';
|
||||
|
||||
import { h } from 'vue';
|
||||
|
||||
import {
|
||||
VBEN_DOC_URL,
|
||||
VBEN_GITHUB_URL,
|
||||
VBEN_PREVIEW_URL,
|
||||
} from '@vben/constants';
|
||||
import { VbenRenderContent } from '@vben-core/shadcn-ui';
|
||||
import { h } from 'vue';
|
||||
|
||||
import { Page } from '../../components';
|
||||
|
||||
|
@@ -1,12 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import type { VbenFormSchema } from '@vben-core/form-ui';
|
||||
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { useVbenForm } from '@vben-core/form-ui';
|
||||
import { VbenButton } from '@vben-core/shadcn-ui';
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
|
@@ -1,12 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import type { VbenFormSchema } from '@vben-core/form-ui';
|
||||
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { useVbenForm } from '@vben-core/form-ui';
|
||||
import { VbenButton } from '@vben-core/shadcn-ui';
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
|
@@ -1,21 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import type { AuthenticationProps } from './types';
|
||||
|
||||
import { watch } from 'vue';
|
||||
import { computed, watch } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben-core/popup-ui';
|
||||
import { Slot, VbenAvatar } from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props extends AuthenticationProps {
|
||||
avatar?: string;
|
||||
zIndex?: number;
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'LoginExpiredModal',
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
avatar: '',
|
||||
zIndex: 0,
|
||||
});
|
||||
|
||||
const open = defineModel<boolean>('open');
|
||||
@@ -28,6 +30,26 @@ watch(
|
||||
modalApi.setState({ isOpen: val });
|
||||
},
|
||||
);
|
||||
|
||||
const getZIndex = computed(() => {
|
||||
return props.zIndex || calcZIndex();
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取最大的zIndex值
|
||||
*/
|
||||
function calcZIndex() {
|
||||
let maxZ = 0;
|
||||
const elements = document.querySelectorAll('*');
|
||||
[...elements].forEach((element) => {
|
||||
const style = window.getComputedStyle(element);
|
||||
const zIndex = style.getPropertyValue('z-index');
|
||||
if (zIndex && !Number.isNaN(Number.parseInt(zIndex))) {
|
||||
maxZ = Math.max(maxZ, Number.parseInt(zIndex));
|
||||
}
|
||||
});
|
||||
return maxZ + 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -39,6 +61,7 @@ watch(
|
||||
:footer="false"
|
||||
:fullscreen-button="false"
|
||||
:header="false"
|
||||
:z-index="getZIndex"
|
||||
class="border-none px-10 py-6 text-center shadow-xl sm:w-[600px] sm:rounded-2xl md:h-[unset]"
|
||||
>
|
||||
<VbenAvatar :src="avatar" class="mx-auto mb-6 size-20" />
|
||||
|
@@ -3,13 +3,12 @@ import type { VbenFormSchema } from '@vben-core/form-ui';
|
||||
|
||||
import type { AuthenticationProps, LoginAndRegisterParams } from './types';
|
||||
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { useVbenForm } from '@vben-core/form-ui';
|
||||
import { VbenButton, VbenCheckbox } from '@vben-core/shadcn-ui';
|
||||
import { cloneDeep } from '@vben-core/shared/utils';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
import ThirdPartyLogin from './third-party-login.vue';
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { VbenButton } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { useQRCode } from '@vueuse/integrations/useQRCode';
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
|
@@ -2,12 +2,11 @@
|
||||
import type { Recordable } from '@vben/types';
|
||||
import type { VbenFormSchema } from '@vben-core/form-ui';
|
||||
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { useVbenForm } from '@vben-core/form-ui';
|
||||
import { VbenButton } from '@vben-core/shadcn-ui';
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
|
@@ -38,7 +38,7 @@ defineEmits(['click']);
|
||||
'border-b-0': index < 3,
|
||||
'pb-4': index > 2,
|
||||
}"
|
||||
class="border-border group w-full cursor-pointer border-b border-r border-t p-4 transition-all hover:shadow-xl md:w-1/2 lg:w-1/3"
|
||||
class="border-border group w-full cursor-pointer border-r border-t p-4 transition-all hover:shadow-xl md:w-1/2 lg:w-1/3"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<VbenIcon
|
||||
|
@@ -38,7 +38,7 @@ defineEmits(['click']);
|
||||
'pb-4': index > 2,
|
||||
'border-b-0': index < 3,
|
||||
}"
|
||||
class="flex-col-center border-border group w-1/3 cursor-pointer border-b border-r border-t py-8 hover:shadow-xl"
|
||||
class="flex-col-center border-border group w-1/3 cursor-pointer border-r border-t py-8 hover:shadow-xl"
|
||||
@click="$emit('click', item)"
|
||||
>
|
||||
<VbenIcon
|
||||
|
@@ -1,12 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import type { FallbackProps } from './fallback';
|
||||
|
||||
import { computed, defineAsyncComponent } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { ArrowLeft, RotateCw } from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
import { VbenButton } from '@vben-core/shadcn-ui';
|
||||
import { computed, defineAsyncComponent } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
interface Props extends FallbackProps {}
|
||||
|
||||
|
Reference in New Issue
Block a user