feat: action buttons

pull/49/MERGE
xingyu4j 2024-11-26 17:21:18 +08:00
parent 44c91c7417
commit 0dcfa13d3b
4 changed files with 108 additions and 0 deletions

View File

@ -0,0 +1,74 @@
<script setup lang="ts">
import type { ActionItem } from './types';
import { computed, type PropType, toRaw } from 'vue';
import { AccessControl } from '@vben/access';
import { IconifyIcon } from '@vben/icons';
import { isBoolean, isFunction, isString } from '@vben/utils';
import { Button } from 'ant-design-vue';
defineOptions({ name: 'ActionButtons' });
const props = defineProps({
actions: {
type: Array as PropType<ActionItem[]>,
default: null,
},
});
function isIfShow(action: ActionItem): boolean {
const ifShow = action.ifShow;
let isIfShow = true;
if (isBoolean(ifShow)) isIfShow = ifShow;
if (isFunction(ifShow)) isIfShow = ifShow(action);
return isIfShow;
}
const getActions = computed(() => {
return (toRaw(props.actions) || [])
.filter((action) => {
return isIfShow(action);
})
.map((action) => {
return {
...action,
auth: isString(action.auth) ? Array.of(action.auth) : action.auth,
};
});
});
</script>
<template>
<div class="flex">
<template v-for="(action, index) in getActions" :key="index">
<AccessControl :codes="action.auth" type="code">
<Button class="mr-1 flex" v-bind="action" :key="index">
<IconifyIcon
v-if="action.preIcon"
:class="{ 'mr-1': !!action.label }"
:icon="action.preIcon"
:size="14"
/>
{{ action.label }}
<IconifyIcon
v-if="action.postIcon"
:class="{ 'mr-1': !!action.label }"
:icon="action.postIcon"
:size="14"
/>
</Button>
</AccessControl>
</template>
</div>
</template>
<style lang="less" scoped>
.ant-btn-link {
padding: 8px 4px;
margin-left: 0;
}
</style>

View File

@ -0,0 +1,20 @@
export enum IconEnum {
ADD = 'ant-design:plus-outlined',
ADD_FOLD = 'ant-design:folder-add-outlined',
AUTH = 'ant-design:safety-certificate-outlined',
DELETE = 'ant-design:delete-outlined',
DOWNLOAD = 'ant-design:cloud-download-outlined',
EDIT = 'clarity:note-edit-line',
EXPORT = 'ant-design:vertical-align-bottom-outlined',
IMPORT = 'ant-design:vertical-align-top-outlined',
LOG = 'ant-design:exception-outlined',
PASSWORD = 'ant-design:key-outlined',
PREVIEW = 'ant-design:eye-outlined',
RESET = 'ant-design:sync-outlined',
SEARCH = 'ant-design:search-outlined',
SEND = 'ant-design:send-outlined',
SETTING = 'ant-design:setting-outlined',
TEST = 'ant-design:deployment-unit-outlined',
UPLOAD = 'ant-design:cloud-upload-outlined',
VIEW = 'ant-design:file-search-outlined',
}

View File

@ -0,0 +1,3 @@
export { default as ActionButtons } from './action-buttons.vue';
export * from './action-icon';
export type * from './types';

View File

@ -0,0 +1,11 @@
import type { ButtonProps, TooltipProps } from 'ant-design-vue';
export interface ActionItem extends ButtonProps {
color?: 'error' | 'success' | 'warning';
preIcon?: string;
postIcon?: string;
label: string;
auth?: string | string[];
tooltip?: string | TooltipProps;
ifShow?: ((...args: any[]) => boolean) | boolean;
}