mirror of
https://github.com/ccmjga/zhilu-admin
synced 2026-04-14 05:00:21 +00:00
fix tablebutton
This commit is contained in:
3752
frontend/src/api/types/schema.d.ts
vendored
3752
frontend/src/api/types/schema.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@@ -61,8 +61,10 @@
|
|||||||
<option :value="'search'">搜索模式</option>
|
<option :value="'search'">搜索模式</option>
|
||||||
<option :value="'chat'">询问模式</option>
|
<option :value="'chat'">询问模式</option>
|
||||||
</select>
|
</select>
|
||||||
<Button :abortable="true" :isLoading="isLoading" :loadingContent="'中止'" :submitContent="'发送'"
|
<TableButton variant="primary" :isLoading="isLoading" :abortable="true"
|
||||||
:handleClick="() => handleSendClick(inputMessage, commandMode)" />
|
@click="() => handleSendClick(inputMessage, commandMode)">
|
||||||
|
{{ isLoading ? '中止' : '发送' }}
|
||||||
|
</TableButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -91,6 +93,7 @@
|
|||||||
import InputButton from "@/components/InputButton.vue";
|
import InputButton from "@/components/InputButton.vue";
|
||||||
import UserDeleteModal from "@/components/PopupModal.vue";
|
import UserDeleteModal from "@/components/PopupModal.vue";
|
||||||
import DepartmentDeleteModal from "@/components/PopupModal.vue";
|
import DepartmentDeleteModal from "@/components/PopupModal.vue";
|
||||||
|
import TableButton from "@/components/TableButton.vue";
|
||||||
import LoadingIcon from "@/components/icons/LoadingIcon.vue";
|
import LoadingIcon from "@/components/icons/LoadingIcon.vue";
|
||||||
import { useAiAction } from "@/composables/ai/useAiAction";
|
import { useAiAction } from "@/composables/ai/useAiAction";
|
||||||
import { useDepartmentQuery } from "@/composables/department/useDepartmentQuery";
|
import { useDepartmentQuery } from "@/composables/department/useDepartmentQuery";
|
||||||
@@ -103,7 +106,6 @@ import { Modal, type ModalInterface, initFlowbite } from "flowbite";
|
|||||||
import { marked } from "marked";
|
import { marked } from "marked";
|
||||||
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
|
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import Button from "../components/Button.vue";
|
|
||||||
import DepartmentUpsertModal from "../components/DepartmentUpsertModal.vue";
|
import DepartmentUpsertModal from "../components/DepartmentUpsertModal.vue";
|
||||||
import UserUpsertModal from "../components/UserUpsertModal.vue";
|
import UserUpsertModal from "../components/UserUpsertModal.vue";
|
||||||
import { useAiChat } from "../composables/ai/useAiChat";
|
import { useAiChat } from "../composables/ai/useAiChat";
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
<template>
|
|
||||||
<button :disabled="disabled" @click="handleClick" type="button" :class="[
|
|
||||||
'text-white',
|
|
||||||
'focus:ring-4',
|
|
||||||
'focus:outline-none',
|
|
||||||
'focus:ring-blue-300',
|
|
||||||
'font-medium',
|
|
||||||
'rounded-lg',
|
|
||||||
'text-center',
|
|
||||||
'inline-flex',
|
|
||||||
'items-center',
|
|
||||||
'justify-center',
|
|
||||||
isLoading && !abortable ? 'bg-blue-400 cursor-not-allowed' : 'bg-blue-700 hover:bg-blue-800',
|
|
||||||
sizeClasses
|
|
||||||
]">
|
|
||||||
<LoadingIcon v-if="isLoading && !abortable" :class="[iconSizeClasses, iconOnly ? '' : 'me-2']" />
|
|
||||||
<StopIcon v-else-if="isLoading && abortable" :class="[iconSizeClasses, iconOnly ? '' : 'me-2']" />
|
|
||||||
<slot v-else-if="!isLoading && $slots.icon" name="icon" :iconSizeClasses="iconSizeClasses"></slot>
|
|
||||||
|
|
||||||
<span v-if="iconOnly && isLoading" class="sr-only">{{ loadingContent }}</span>
|
|
||||||
<span v-else-if="iconOnly && !isLoading && !$slots.icon" class="sr-only">{{ submitContent }}</span>
|
|
||||||
<template v-else-if="!iconOnly">
|
|
||||||
{{ isLoading ? loadingContent : submitContent }}
|
|
||||||
</template>
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, useSlots } from "vue";
|
|
||||||
import LoadingIcon from "./icons/LoadingIcon.vue";
|
|
||||||
import StopIcon from "./icons/StopIcon.vue";
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
loadingContent?: string;
|
|
||||||
submitContent: string;
|
|
||||||
isLoading: boolean;
|
|
||||||
abortable: boolean;
|
|
||||||
handleClick: (event: Event) => void;
|
|
||||||
size?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
||||||
iconOnly?: boolean;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const slots = useSlots();
|
|
||||||
|
|
||||||
const sizeClasses = computed(() => {
|
|
||||||
if (props.iconOnly && slots.icon) {
|
|
||||||
switch (props.size) {
|
|
||||||
case "xs":
|
|
||||||
return "p-1.5";
|
|
||||||
case "sm":
|
|
||||||
return "p-2";
|
|
||||||
case "lg":
|
|
||||||
return "p-3";
|
|
||||||
case "xl":
|
|
||||||
return "p-3.5";
|
|
||||||
default:
|
|
||||||
return "p-2.5";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (props.size) {
|
|
||||||
case "xs":
|
|
||||||
return "text-xs px-3 py-1.5";
|
|
||||||
case "sm":
|
|
||||||
return "text-sm px-3.5 py-2";
|
|
||||||
case "lg":
|
|
||||||
return "text-base px-5 py-3";
|
|
||||||
case "xl":
|
|
||||||
return "text-base px-6 py-3.5";
|
|
||||||
default:
|
|
||||||
return "text-sm px-4 py-2.5";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const iconSizeClasses = computed(() => {
|
|
||||||
switch (props.size) {
|
|
||||||
case "xs":
|
|
||||||
return "w-3.5 h-3.5";
|
|
||||||
case "sm":
|
|
||||||
return "w-4 h-4";
|
|
||||||
case "lg":
|
|
||||||
return "w-5 h-5";
|
|
||||||
case "xl":
|
|
||||||
return "w-6 h-6";
|
|
||||||
default:
|
|
||||||
return "w-4.5 h-4.5";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const loadingStyle = computed<string>(() => {
|
|
||||||
return "";
|
|
||||||
});
|
|
||||||
|
|
||||||
const disabled = computed(() => {
|
|
||||||
return !props.abortable && props.isLoading;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<button :class="[
|
<button :class="[
|
||||||
'flex items-center justify-center gap-x-1 whitespace-nowrap font-medium rounded-lg focus:ring-4 focus:outline-none',
|
'flex items-center justify-center gap-x-1 whitespace-nowrap font-medium rounded-lg focus:ring-4 focus:outline-none',
|
||||||
sizeClasses,
|
sizeClasses,
|
||||||
colorClasses,
|
colorClasses,
|
||||||
disabled ? 'opacity-50 cursor-not-allowed' : '',
|
(disabled || (isLoading && !abortable)) ? 'opacity-50 cursor-not-allowed' : '',
|
||||||
className
|
className
|
||||||
]" :disabled="disabled" @click="handleClick" type="button">
|
]" :disabled="disabled || (isLoading && !abortable)" @click="handleClick" type="button">
|
||||||
<slot name="icon"></slot>
|
<StopIcon v-if="isLoading && abortable" :class="iconSizeClasses" />
|
||||||
<span>
|
<slot v-else name="icon"></slot>
|
||||||
<slot></slot>
|
<span>
|
||||||
</span>
|
<slot></slot>
|
||||||
</button>
|
</span>
|
||||||
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
import StopIcon from "./icons/StopIcon.vue";
|
||||||
|
|
||||||
export type ButtonVariant =
|
export type ButtonVariant =
|
||||||
| "primary"
|
| "primary"
|
||||||
@@ -36,6 +38,10 @@ const props = defineProps<{
|
|||||||
className?: string;
|
className?: string;
|
||||||
/** 是否为移动端尺寸 */
|
/** 是否为移动端尺寸 */
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
|
/** 是否处于加载状态 */
|
||||||
|
isLoading?: boolean;
|
||||||
|
/** 是否可中止 */
|
||||||
|
abortable?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -82,9 +88,20 @@ const sizeClasses = computed(() => {
|
|||||||
return sizes[props.size || "md"];
|
return sizes[props.size || "md"];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** 图标尺寸样式映射 */
|
||||||
|
const iconSizeClasses = computed(() => {
|
||||||
|
const sizes: Record<ButtonSize, string> = {
|
||||||
|
xs: "w-3.5 h-3.5",
|
||||||
|
sm: "w-4 h-4",
|
||||||
|
md: "w-4.5 h-4.5",
|
||||||
|
lg: "w-5 h-5",
|
||||||
|
};
|
||||||
|
return sizes[props.size || "md"];
|
||||||
|
});
|
||||||
|
|
||||||
/** 处理点击事件 */
|
/** 处理点击事件 */
|
||||||
const handleClick = (event: MouseEvent) => {
|
const handleClick = (event: MouseEvent) => {
|
||||||
if (!props.disabled) {
|
if (!props.disabled && !(props.isLoading && !props.abortable)) {
|
||||||
emit("click", event);
|
emit("click", event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
'inline': true,
|
'inline': true,
|
||||||
[textColor]: true,
|
[textColor]: true,
|
||||||
[size]: true,
|
[size]: true,
|
||||||
'me-2': true
|
|
||||||
}" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
|
}" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
|
||||||
<path d="M7 5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2H7Z" />
|
<path d="M7 5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2H7Z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
||||||
@update:values="updateFilterValues">
|
@update:values="updateFilterValues">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<Button :handleClick="() => handleUpsertDepartmentClick()" :isLoading="false" :abortable="false"
|
<TableButton variant="primary" @click="handleUpsertDepartmentClick()" class="w-full sm:w-auto">
|
||||||
submitContent="新增部门" class="w-full sm:w-auto">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusIcon class="w-4 h-4 me-2" />
|
<PlusIcon class="w-4 h-4" />
|
||||||
</template>
|
</template>
|
||||||
</Button>
|
新增部门
|
||||||
|
</TableButton>
|
||||||
</template>
|
</template>
|
||||||
</TableFilterForm>
|
</TableFilterForm>
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||||
import Button from "@/components/Button.vue";
|
|
||||||
import DepartmentUpsertModal from "@/components/DepartmentUpsertModal.vue";
|
import DepartmentUpsertModal from "@/components/DepartmentUpsertModal.vue";
|
||||||
import MobileCardList from "@/components/MobileCardList.vue";
|
import MobileCardList from "@/components/MobileCardList.vue";
|
||||||
import DepartmentDeleteModal from "@/components/PopupModal.vue";
|
import DepartmentDeleteModal from "@/components/PopupModal.vue";
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
||||||
@update:values="updateFilterValues">
|
@update:values="updateFilterValues">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<Button :handleClick="() => handleUpsertPermissionClick(undefined)" :isLoading="false" :abortable="false"
|
<TableButton variant="primary" @click="handleUpsertPermissionClick(undefined)" class="w-full sm:w-auto">
|
||||||
submitContent="新增权限" class="w-full sm:w-auto">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusIcon class="w-4 h-4 me-2" />
|
<PlusIcon class="w-4 h-4" />
|
||||||
</template>
|
</template>
|
||||||
</Button>
|
新增权限
|
||||||
|
</TableButton>
|
||||||
</template>
|
</template>
|
||||||
</TableFilterForm>
|
</TableFilterForm>
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { components } from "@/api/types/schema";
|
import type { components } from "@/api/types/schema";
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||||
import Button from "@/components/Button.vue";
|
|
||||||
import MobileCardList from "@/components/MobileCardList.vue";
|
import MobileCardList from "@/components/MobileCardList.vue";
|
||||||
import PermissionUpsertModal from "@/components/PermissionUpsertModal.vue";
|
import PermissionUpsertModal from "@/components/PermissionUpsertModal.vue";
|
||||||
import PermissionDeleteModal from "@/components/PopupModal.vue";
|
import PermissionDeleteModal from "@/components/PopupModal.vue";
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
||||||
@update:values="updateFilterValues">
|
@update:values="updateFilterValues">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<Button :handleClick="() => handleUpsertPositionClick()" :isLoading="false" :abortable="false"
|
<TableButton variant="primary" @click="handleUpsertPositionClick()" class="w-full sm:w-auto">
|
||||||
submitContent="新增岗位" class="w-full sm:w-auto">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusIcon class="w-4 h-4 me-2" />
|
<PlusIcon class="w-4 h-4" />
|
||||||
</template>
|
</template>
|
||||||
</Button>
|
新增岗位
|
||||||
|
</TableButton>
|
||||||
</template>
|
</template>
|
||||||
</TableFilterForm>
|
</TableFilterForm>
|
||||||
|
|
||||||
@@ -99,10 +99,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||||
import Button from "@/components/Button.vue";
|
|
||||||
import MobileCardList from "@/components/MobileCardList.vue";
|
import MobileCardList from "@/components/MobileCardList.vue";
|
||||||
import PositionDeleteModal from "@/components/PopupModal.vue";
|
import PositionDeleteModal from "@/components/PopupModal.vue";
|
||||||
import PositionUpsertModal from "@/components/PositionUpsertModal.vue";
|
import PositionUpsertModal from "@/components/PositionUpsertModal.vue";
|
||||||
|
import TableButton from "@/components/TableButton.vue";
|
||||||
import TableFilterForm from "@/components/TableFilterForm.vue";
|
import TableFilterForm from "@/components/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/TableFilterForm.vue";
|
||||||
import TableFormLayout from "@/components/TableFormLayout.vue";
|
import TableFormLayout from "@/components/TableFormLayout.vue";
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
<TableFilterForm :filters="filterConfig" :initialValues="filterValues" @search="handleSearch"
|
||||||
@update:values="updateFilterValues">
|
@update:values="updateFilterValues">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<Button :handleClick="() => handleUpsertRoleClick(undefined)" :isLoading="false" :abortable="false"
|
<TableButton variant="primary" @click="handleUpsertRoleClick(undefined)" class="w-full sm:w-auto">
|
||||||
submitContent="新增角色" class="w-full sm:w-auto">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusIcon class="w-4 h-4 me-2" />
|
<PlusIcon class="w-4 h-4" />
|
||||||
</template>
|
</template>
|
||||||
</Button>
|
新增角色
|
||||||
|
</TableButton>
|
||||||
</template>
|
</template>
|
||||||
</TableFilterForm>
|
</TableFilterForm>
|
||||||
|
|
||||||
@@ -123,10 +123,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||||
import Button from "@/components/Button.vue";
|
|
||||||
import MobileCardList from "@/components/MobileCardList.vue";
|
import MobileCardList from "@/components/MobileCardList.vue";
|
||||||
import RoleDeleteModal from "@/components/PopupModal.vue";
|
import RoleDeleteModal from "@/components/PopupModal.vue";
|
||||||
import RoleUpsertModal from "@/components/RoleUpsertModal.vue";
|
import RoleUpsertModal from "@/components/RoleUpsertModal.vue";
|
||||||
|
import TableButton from "@/components/TableButton.vue";
|
||||||
import TableFilterForm from "@/components/TableFilterForm.vue";
|
import TableFilterForm from "@/components/TableFilterForm.vue";
|
||||||
import type { FilterItem } from "@/components/TableFilterForm.vue";
|
import type { FilterItem } from "@/components/TableFilterForm.vue";
|
||||||
import TableFormLayout from "@/components/TableFormLayout.vue";
|
import TableFormLayout from "@/components/TableFormLayout.vue";
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<template #actions>
|
<template #actions>
|
||||||
<TableButton variant="primary" @click="() => handleUpsertUserClick(undefined)">
|
<TableButton variant="primary" @click="() => handleUpsertUserClick(undefined)">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusIcon class="w-4 h-4 me-2" />
|
<PlusIcon class="w-4 h-4" />
|
||||||
</template>
|
</template>
|
||||||
新增用户
|
新增用户
|
||||||
</TableButton>
|
</TableButton>
|
||||||
@@ -161,9 +161,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||||
import Button from "@/components/Button.vue";
|
|
||||||
import UserDeleteModal from "@/components/PopupModal.vue";
|
import UserDeleteModal from "@/components/PopupModal.vue";
|
||||||
import SortIcon from "@/components/SortIcon.vue";
|
import SortIcon from "@/components/SortIcon.vue";
|
||||||
|
import TableButton from "@/components/TableButton.vue";
|
||||||
import TableFilterForm, {
|
import TableFilterForm, {
|
||||||
type FilterItem,
|
type FilterItem,
|
||||||
} from "@/components/TableFilterForm.vue";
|
} from "@/components/TableFilterForm.vue";
|
||||||
@@ -185,7 +186,6 @@ import { useRouter } from "vue-router";
|
|||||||
import type { components } from "../api/types/schema";
|
import type { components } from "../api/types/schema";
|
||||||
import useAlertStore from "../composables/store/useAlertStore";
|
import useAlertStore from "../composables/store/useAlertStore";
|
||||||
import { useUserUpsert } from "../composables/user/useUserUpsert";
|
import { useUserUpsert } from "../composables/user/useUserUpsert";
|
||||||
import TableButton from "@/components/TableButton.vue";
|
|
||||||
|
|
||||||
const filterConfig: FilterItem[] = [
|
const filterConfig: FilterItem[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user