<script lang="ts" setup>
|
import type { TreeActionItem, TreeActionType } from '@jnpf/ui';
|
import type { ActionItem, BasicColumn } from '@jnpf/ui/vxeTable';
|
|
import { computed, h, nextTick, onMounted, reactive, ref, toRefs, unref } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { BasicLeftTree } from '@jnpf/ui';
|
import { BasicForm, useForm } from '@jnpf/ui/form';
|
import { useModal } from '@jnpf/ui/modal';
|
import { BasicVxeTable, TableAction, useVxeTable } from '@jnpf/ui/vxeTable';
|
import { downloadByUrl } from '@jnpf/utils';
|
|
import { DeleteOutlined, DoubleLeftOutlined, DoubleRightOutlined, FormOutlined, PlusOutlined, UserOutlined } from '@ant-design/icons-vue';
|
import { Tag } from 'ant-design-vue';
|
|
import { delOrganize, getOrganizeSyncList } from '#/api/permission/organize';
|
import { delPosition, getPositionList, setDutyPosition, setDutyUser } from '#/api/permission/position';
|
import { addRoles, getRoleList, removeRoles } from '#/api/permission/roleRelation';
|
import { addUserRelation, getUserRelation, removeUserRelation } from '#/api/permission/userRelation';
|
import { $t } from '#/locales';
|
import ImportModal from '#/views/permission/common/components/ImportModal.vue';
|
|
import { importInfo } from '../common/helper/config';
|
import OrganizeForm from './OrganizeForm.vue';
|
import PositionForm from './PositionForm.vue';
|
|
defineOptions({ name: 'PermissionOrganize' });
|
|
interface State {
|
organizeTreeData: any[];
|
organizeTreeLoading: boolean;
|
organizeKey: number;
|
positionTreeData: any[];
|
positionTreeLoading: boolean;
|
positionKey: number;
|
activeKey: number;
|
searchInfo: any;
|
treeSearchInfo: any;
|
isOrganizeAdvanced: boolean;
|
isPositionAdvanced: boolean;
|
organizeTooltipKey: number;
|
positionTooltipKey: number;
|
}
|
|
const state = reactive<State>({
|
organizeTreeData: [],
|
organizeTreeLoading: false,
|
organizeKey: Date.now(),
|
positionTreeData: [],
|
positionTreeLoading: false,
|
positionKey: Date.now(),
|
activeKey: 0,
|
searchInfo: {
|
organizeId: '',
|
organizeName: '',
|
positionId: '',
|
},
|
treeSearchInfo: {},
|
isOrganizeAdvanced: false,
|
isPositionAdvanced: false,
|
organizeTooltipKey: 0,
|
positionTooltipKey: 0,
|
});
|
const { activeKey, searchInfo, isOrganizeAdvanced, isPositionAdvanced, organizeTooltipKey, positionTooltipKey } = toRefs(state);
|
const { createMessage, createConfirm } = useMessage();
|
const organizeTreeRef = ref<Nullable<TreeActionType>>(null);
|
const positionTreeRef = ref<Nullable<TreeActionType>>(null);
|
const [registerImportModal, { openModal: openImportModal }] = useModal();
|
const [registerOrganizeForm, { openModal: openOrganizeFormModal }] = useModal();
|
const [registerPositionForm, { openModal: openPositionFormModal }] = useModal();
|
const userColumns: BasicColumn[] = [
|
{ title: '账号', dataIndex: 'account', width: 100 },
|
{ title: '姓名', dataIndex: 'realName', width: 150, slots: { default: 'realName' } },
|
{ title: '性别', dataIndex: 'gender', width: 90, align: 'center' },
|
{ title: '手机', dataIndex: 'mobilePhone', width: 120 },
|
{ title: '所属岗位', dataIndex: 'position', minWidth: 120 },
|
{ title: '状态', dataIndex: 'enabledMark', width: 70, align: 'center', slots: { default: 'enabledMark' } },
|
];
|
const [registerUserTable, { reload: reloadUserTable, getSelectRowKeys: getUserSelectRowKeys, clearSelectedRowKeys: clearUserSelectedRowKeys }] = useVxeTable({
|
api: getUserRelation,
|
columns: userColumns,
|
immediate: false,
|
clickToRowSelect: false,
|
});
|
const roleColumns: BasicColumn[] = [
|
{ title: '角色编码', dataIndex: 'enCode', width: 200 },
|
{ title: '角色名称', dataIndex: 'fullName', minWidth: 200 },
|
{ title: '角色说明', dataIndex: 'description', minWidth: 200 },
|
];
|
const [registerRoleTable, { reload: reloadRoleTable, getSelectRowKeys: getRoleSelectRowKeys, clearSelectedRowKeys: clearRoleSelectedRowKeys }] = useVxeTable({
|
api: getRoleList,
|
columns: roleColumns,
|
rowSelection: { type: 'checkbox' },
|
clickToRowSelect: false,
|
immediate: false,
|
});
|
const organizeActionList: TreeActionItem[] = [
|
{
|
render: (node) => {
|
return h(PlusOutlined, {
|
class: 'ml-[4px]',
|
title: '新建子组织',
|
onClick: (e) => {
|
e.stopPropagation();
|
addOrUpdateOrganizeHandle('', node);
|
},
|
});
|
},
|
},
|
{
|
render: (node) => {
|
return h(FormOutlined, {
|
class: 'ml-[4px]',
|
title: '编辑',
|
onClick: (e) => {
|
e.stopPropagation();
|
addOrUpdateOrganizeHandle(node.id);
|
},
|
});
|
},
|
},
|
{
|
render: (node) => {
|
return h(DeleteOutlined, {
|
class: 'ml-[4px]',
|
title: '删除',
|
onClick: (e) => {
|
e.stopPropagation();
|
handleDelOrganize(node.id);
|
},
|
});
|
},
|
},
|
];
|
const positionActionList: TreeActionItem[] = [
|
{
|
render: (node) => {
|
return (
|
node.allowDuty &&
|
h(UserOutlined, {
|
class: 'ml-[4px]',
|
title: '设为责任岗位',
|
onClick: (e) => {
|
e.stopPropagation();
|
handleSetDutyPosition(node.id);
|
},
|
})
|
);
|
},
|
},
|
{
|
render: (node) => {
|
return (
|
!node.defaultMark &&
|
h(FormOutlined, {
|
class: 'ml-[4px]',
|
title: '编辑',
|
onClick: (e) => {
|
e.stopPropagation();
|
addOrUpdatePositionHandle(node.id);
|
},
|
})
|
);
|
},
|
},
|
{
|
render: (node) => {
|
return (
|
!node.defaultMark &&
|
h(DeleteOutlined, {
|
class: 'ml-[4px]',
|
title: '删除',
|
onClick: (e) => {
|
e.stopPropagation();
|
handleDelPosition(node.id);
|
},
|
})
|
);
|
},
|
},
|
];
|
const positionExtraInfo: TreeActionItem = {
|
render: (node) => {
|
return (
|
node.isDutyPosition &&
|
h(
|
Tag,
|
{
|
class: 'mr-0',
|
color: 'processing',
|
},
|
() => '责任岗位',
|
)
|
);
|
},
|
};
|
const [registerForm, { submit: searchFormSubmit }] = useForm({
|
baseColProps: { span: 6 },
|
showActionButtonGroup: true,
|
showAdvancedButton: true,
|
compact: true,
|
});
|
|
const getFormSchemas = computed(() => {
|
const keyword = {
|
field: 'keyword',
|
label: $t('common.keyword'),
|
component: 'Input',
|
componentProps: {
|
placeholder: $t('common.enterKeyword'),
|
submitOnPressEnter: true,
|
},
|
};
|
const enabledMark = {
|
field: 'enabledMark',
|
label: '状态',
|
component: 'Select',
|
componentProps: {
|
options: [
|
{ fullName: '启用', id: 1 },
|
{ fullName: '禁用', id: 0 },
|
{ fullName: '锁定', id: 2 },
|
],
|
},
|
};
|
const showSubOrganize = {
|
field: 'showSubOrganize',
|
label: '显示子孙组织用户',
|
component: 'Select',
|
defaultValue: 0,
|
componentProps: {
|
options: [
|
{ fullName: '是', id: 1 },
|
{ fullName: '否', id: 0 },
|
],
|
},
|
};
|
const userSchemas: any[] = state.treeSearchInfo.positionId ? [keyword, enabledMark] : [keyword, enabledMark, showSubOrganize];
|
return state.activeKey === 0 ? userSchemas : [keyword];
|
});
|
const getUserTableBindValue = computed(() => {
|
const data: any = {};
|
if (state.treeSearchInfo.positionId) {
|
data.actionColumn = {
|
width: 100,
|
title: '操作',
|
dataIndex: 'action',
|
};
|
data.rowSelection = { type: 'checkbox' };
|
}
|
return data;
|
});
|
const getOrgTreeBindValue = computed(() => ({
|
showToolbar: false,
|
showSearch: false,
|
defaultExpandAll: false,
|
treeData: state.organizeTreeData,
|
loading: state.organizeTreeLoading,
|
key: state.organizeKey,
|
actionList: organizeActionList,
|
loadData: onLoadData,
|
onSelect: handleOrganizeTreeSelect,
|
}));
|
const getPosTreeBindValue = computed(() => ({
|
showToolbar: false,
|
showSearch: false,
|
treeData: state.positionTreeData,
|
loading: state.positionTreeLoading,
|
key: state.positionKey,
|
actionList: positionActionList,
|
extraInfo: positionExtraInfo,
|
onSelect: handlePositionTreeSelect,
|
}));
|
|
function initOrganizeList() {
|
state.organizeTreeLoading = true;
|
getOrganizeSyncList({ parentId: '0' })
|
.then((res) => {
|
state.organizeTreeData = res.data.list || [];
|
state.organizeKey = Date.now();
|
state.organizeTreeLoading = false;
|
nextTick(() => {
|
state.treeSearchInfo.organizeId = state.organizeTreeData[0]?.id;
|
state.treeSearchInfo.organizeName = state.organizeTreeData[0]?.fullName;
|
unref(organizeTreeRef)?.setSelectedKeys([state.treeSearchInfo.organizeId]);
|
initPositionList(false);
|
handleReset();
|
});
|
})
|
.catch(() => {
|
state.organizeTreeLoading = false;
|
});
|
}
|
function onLoadData(node) {
|
return new Promise((resolve: (value?: unknown) => void) => {
|
getOrganizeSyncList({ parentId: node?.id }).then((res) => {
|
const data = res.data.list.map((o) => {
|
if (o.hasChildren) o.children = [];
|
return o;
|
});
|
unref(organizeTreeRef)?.updateNodeByKey(node.eventKey, { children: data, isLeaf: !data.length });
|
resolve();
|
});
|
});
|
}
|
function handleOrganizeEvent({ key }) {
|
if (key === 0) return addOrUpdateOrganizeHandle();
|
if (key === 1) return handleImport('organize');
|
if (key === 2) return handleExport('organize');
|
}
|
function handlePositionEvent({ key }) {
|
if (key === 0) return addOrUpdatePositionHandle();
|
if (key === 1) return handleImport('position');
|
if (key === 2) return handleExport('position');
|
}
|
function addOrUpdateOrganizeHandle(id = '', node?) {
|
openOrganizeFormModal(true, { id, parentId: node?.id, parentName: node?.fullName, category: node?.category });
|
}
|
function handleDelOrganize(id) {
|
createConfirm({
|
iconType: 'warning',
|
title: $t('common.tipTitle'),
|
content: $t('common.delTip'),
|
onOk: () => {
|
delOrganize(id).then((res) => {
|
createMessage.success(res.msg);
|
initOrganizeList();
|
});
|
},
|
});
|
}
|
function addOrUpdatePositionHandle(id = '') {
|
openPositionFormModal(true, { id, organizeId: state.treeSearchInfo.organizeId, organizeName: state.treeSearchInfo.organizeName });
|
}
|
function handleDelPosition(id) {
|
createConfirm({
|
iconType: 'warning',
|
title: $t('common.tipTitle'),
|
content: $t('common.delTip'),
|
onOk: () => {
|
delPosition(id).then((res) => {
|
createMessage.success(res.msg);
|
initPositionList();
|
});
|
},
|
});
|
}
|
function handleSetDutyPosition(id) {
|
createConfirm({
|
iconType: 'warning',
|
title: $t('common.tipTitle'),
|
content: '确定将当前岗位设置为责任岗位,是否继续?',
|
onOk: () => {
|
setDutyPosition(id, state.treeSearchInfo.organizeId).then((res) => {
|
createMessage.success(res.msg);
|
initPositionList(false);
|
});
|
},
|
});
|
}
|
function handleSetDutyUser(userId) {
|
createConfirm({
|
iconType: 'warning',
|
title: $t('common.tipTitle'),
|
content: '确定将当前岗位设置为岗位责任人,是否继续?',
|
onOk: () => {
|
setDutyUser(state.treeSearchInfo.positionId, userId).then((res) => {
|
createMessage.success(res.msg);
|
reload();
|
});
|
},
|
});
|
}
|
function handleExport(type) {
|
const query = {
|
dataType: 1,
|
};
|
importInfo[type].exportExcel(query).then((res) => {
|
if (!res.data.url) return;
|
downloadByUrl({ url: res.data.url });
|
});
|
}
|
function handleImport(type) {
|
openImportModal(true, { type });
|
}
|
function initPositionList(isReload = true) {
|
state.positionTreeLoading = true;
|
getPositionList({ organizeId: state.treeSearchInfo.organizeId })
|
.then((res) => {
|
state.positionTreeData = res.data.list || [];
|
state.positionKey = Date.now();
|
state.positionTreeLoading = false;
|
nextTick(() => {
|
if (isReload) {
|
state.treeSearchInfo.positionId = state.positionTreeData[0]?.id;
|
unref(positionTreeRef)?.setSelectedKeys([state.treeSearchInfo.positionId]);
|
handleReset();
|
}
|
});
|
})
|
.catch(() => {
|
state.positionTreeLoading = false;
|
});
|
}
|
function handleOrganizeTreeSelect(id, item) {
|
if (id == state.treeSearchInfo.organizeId) return;
|
state.treeSearchInfo.positionId = '';
|
state.treeSearchInfo.organizeId = id;
|
state.treeSearchInfo.organizeName = item.fullName;
|
initPositionList(false);
|
handleReset();
|
}
|
function handlePositionTreeSelect(id) {
|
if (id == state.treeSearchInfo.positionId) return;
|
state.treeSearchInfo.positionId = id;
|
handleReset();
|
}
|
function handleSubmit(data) {
|
const obj = {};
|
for (const [key, value] of Object.entries(data)) {
|
if (value || value == 0) {
|
if (Array.isArray(value)) {
|
if (value.length) obj[key] = value;
|
} else {
|
obj[key] = value;
|
}
|
}
|
}
|
state.searchInfo = { ...state.treeSearchInfo, ...obj };
|
reload();
|
}
|
function handleReset() {
|
state.searchInfo = state.treeSearchInfo;
|
searchFormSubmit();
|
}
|
function reload() {
|
nextTick(() => {
|
state.activeKey === 0 ? clearUserSelectedRowKeys() : clearRoleSelectedRowKeys();
|
state.activeKey === 0 ? reloadUserTable() : reloadRoleTable();
|
});
|
}
|
function handleAddPositionUser(ids) {
|
addUserRelation({ objectId: state.treeSearchInfo.positionId, userIds: ids, objectType: 'position' }).then((res) => {
|
createMessage.success(res.msg);
|
reload();
|
});
|
}
|
function handleAddRole(ids) {
|
const objectId = state.treeSearchInfo.positionId ? state.treeSearchInfo.positionId : state.treeSearchInfo.organizeId;
|
addRoles({ objectId, ids, type: state.searchInfo.positionId ? 'position' : 'organize' }).then((res) => {
|
createMessage.success(res.msg);
|
reload();
|
});
|
}
|
function handleBatchRemove(type) {
|
const ids = type == 'user' ? getUserSelectRowKeys() : getRoleSelectRowKeys();
|
if (!ids.length) return createMessage.error($t('common.selectDataTip'));
|
const name = state.searchInfo.positionId ? '岗位' : '组织';
|
createConfirm({
|
iconType: 'warning',
|
title: $t('common.tipTitle'),
|
content: `此操作将从当前${name}中移除选中的${state.activeKey == 0 ? '用户' : `${name}角色`},是否继续?`,
|
onOk: () => {
|
const objectId = state.treeSearchInfo.positionId ? state.treeSearchInfo.positionId : state.treeSearchInfo.organizeId;
|
const data =
|
type == 'user'
|
? {
|
objectId,
|
userIds: ids,
|
objectType: 'position',
|
}
|
: {
|
objectId,
|
ids,
|
type: state.searchInfo.positionId ? 'position' : 'organize',
|
};
|
const method = type == 'user' ? removeUserRelation : removeRoles;
|
method(data).then((res) => {
|
createMessage.success(res.msg);
|
type == 'user' ? clearUserSelectedRowKeys() : clearRoleSelectedRowKeys();
|
reload();
|
});
|
},
|
});
|
}
|
function getTableActions(record): ActionItem[] {
|
return [
|
{
|
disabled: !!record.isDutyUser,
|
label: '设为责任人',
|
onClick: handleSetDutyUser.bind(null, record.id),
|
},
|
];
|
}
|
function toggleOrganizeAdvanced() {
|
state.isOrganizeAdvanced = !state.isOrganizeAdvanced;
|
state.organizeTooltipKey = Date.now();
|
}
|
function togglePositionAdvanced() {
|
state.isPositionAdvanced = !state.isPositionAdvanced;
|
state.positionTooltipKey = Date.now();
|
}
|
|
onMounted(() => {
|
initOrganizeList();
|
});
|
</script>
|
<template>
|
<div class="relative flex h-full flex-col">
|
<a-alert show-icon type="warning" class="mb-[10px]">
|
<template #message>
|
组织、权限模块的详细说明介绍,请查阅使用帮助,<a class="link-text" target="_blank" href="https://usermanuals.jnpfsoft.com/#/docs/11007">点击查看</a>
|
</template>
|
</a-alert>
|
<div class="jnpf-content-wrapper flex-1">
|
<div class="jnpf-content-wrapper-left organize-tree" v-show="!isPositionAdvanced" :class="isOrganizeAdvanced ? 'organize-tree-advanced' : '!w-[220px]'">
|
<BasicLeftTree title="组织" ref="organizeTreeRef" v-bind="getOrgTreeBindValue">
|
<template #headerToolbar>
|
<a-dropdown placement="bottom">
|
<template #overlay>
|
<a-menu @click="handleOrganizeEvent">
|
<a-menu-item :key="0"><i class="icon-ym icon-ym-btn-add pr-[5px]"></i>新建组织</a-menu-item>
|
<a-menu-item :key="1"><i class="icon-ym icon-ym-btn-download pr-[5px]"></i>导入组织</a-menu-item>
|
<a-menu-item :key="2"><i class="icon-ym icon-ym-btn-upload pr-[5px]"></i>导出组织</a-menu-item>
|
</a-menu>
|
</template>
|
<i class="icon-ym icon-ym-btn-add cursor-pointer"></i>
|
</a-dropdown>
|
<a-tooltip placement="top" :title="isOrganizeAdvanced ? $t('component.form.fold') : $t('component.form.unfold')" :key="organizeTooltipKey">
|
<div class="trigger-btn" @click="toggleOrganizeAdvanced">
|
<DoubleLeftOutlined v-if="isOrganizeAdvanced" />
|
<DoubleRightOutlined v-else />
|
</div>
|
</a-tooltip>
|
</template>
|
</BasicLeftTree>
|
</div>
|
<div class="jnpf-content-wrapper-left position-tree" v-show="!isOrganizeAdvanced" :class="isPositionAdvanced ? '!w-[440px]' : '!w-[220px]'">
|
<BasicLeftTree title="岗位" ref="positionTreeRef" v-bind="getPosTreeBindValue">
|
<template #headerToolbar>
|
<a-dropdown placement="bottom">
|
<template #overlay>
|
<a-menu @click="handlePositionEvent">
|
<a-menu-item :key="0"><i class="icon-ym icon-ym-btn-add pr-[5px]"></i>新建岗位</a-menu-item>
|
<a-menu-item :key="1"><i class="icon-ym icon-ym-btn-download pr-[5px]"></i>导入岗位</a-menu-item>
|
<a-menu-item :key="2"><i class="icon-ym icon-ym-btn-upload pr-[5px]"></i>导出岗位</a-menu-item>
|
</a-menu>
|
</template>
|
<i class="icon-ym icon-ym-btn-add cursor-pointer"></i>
|
</a-dropdown>
|
<a-tooltip placement="top" :title="isPositionAdvanced ? $t('component.form.fold') : $t('component.form.unfold')" :key="positionTooltipKey">
|
<div class="trigger-btn" @click="togglePositionAdvanced">
|
<DoubleLeftOutlined v-if="isPositionAdvanced" />
|
<DoubleRightOutlined v-else />
|
</div>
|
</a-tooltip>
|
</template>
|
</BasicLeftTree>
|
</div>
|
<div class="jnpf-content-wrapper-center">
|
<div class="jnpf-content-wrapper-search-box">
|
<BasicForm class="search-form" @register="registerForm" :schemas="getFormSchemas" @submit="handleSubmit" @reset="handleReset" />
|
</div>
|
<div class="jnpf-content-wrapper-content bg-white">
|
<a-tabs v-model:active-key="activeKey" class="jnpf-content-wrapper-tabs tabs-contain" @change="reload">
|
<a-tab-pane :key="0" tab="用户列表">
|
<BasicVxeTable @register="registerUserTable" :search-info="searchInfo" v-bind="getUserTableBindValue">
|
<template #tableTitle v-if="searchInfo.positionId">
|
<jnpf-users-select
|
required
|
button-type="button"
|
button-show-type="primary"
|
:show-selected-list="false"
|
modal-title="添加用户"
|
multiple
|
@change="handleAddPositionUser" />
|
<a-button type="link" @click="handleBatchRemove('user')"><i class="icon-ym icon-ym-add-cancel"></i>移除</a-button>
|
</template>
|
<template #enabledMark="{ record }">
|
<a-tag :color="record.enabledMark == 1 ? 'success' : record.enabledMark == 2 ? 'warning' : 'error'">
|
{{ record.enabledMark == 1 ? '启用' : record.enabledMark == 2 ? '锁定' : '禁用' }}
|
</a-tag>
|
</template>
|
<template #realName="{ record }">
|
<div class="flex">
|
<span class="overflow-hidden text-ellipsis whitespace-nowrap" :title="record.realName">{{ record.realName }}</span>
|
<a-tag color="processing" class="ml-[5px]" v-if="!!record.isDutyUser"> 责任人</a-tag>
|
</div>
|
</template>
|
<template #action="{ record }">
|
<TableAction :actions="getTableActions(record)" />
|
</template>
|
</BasicVxeTable>
|
</a-tab-pane>
|
<a-tab-pane :key="1" :tab="`${!searchInfo.positionId ? '组织' : '岗位'}角色`">
|
<BasicVxeTable @register="registerRoleTable" :search-info="searchInfo">
|
<template #headerTop>
|
<a-alert :message="`给当前${!searchInfo.positionId ? '组织' : '岗位'}节点附加额外权限`" show-icon type="warning" class="mt-[10px]" />
|
</template>
|
<template #tableTitle>
|
<jnpf-role-select
|
required
|
:role-type="searchInfo.positionId ? 'position' : 'organize'"
|
button-type="button"
|
button-show-type="primary"
|
:show-selected-list="false"
|
:modal-title="`添加${!searchInfo.positionId ? '组织' : '岗位'}角色`"
|
multiple
|
has-sys
|
@change="handleAddRole" />
|
<a-button type="link" @click="handleBatchRemove('role')"><i class="icon-ym icon-ym-add-cancel"></i>移除</a-button>
|
</template>
|
</BasicVxeTable>
|
</a-tab-pane>
|
</a-tabs>
|
</div>
|
</div>
|
</div>
|
<ImportModal @register="registerImportModal" @reload="initOrganizeList" />
|
<OrganizeForm @register="registerOrganizeForm" @reload="initOrganizeList" />
|
<PositionForm @register="registerPositionForm" @reload="initPositionList" />
|
</div>
|
</template>
|
<style lang="scss" scoped>
|
.trigger-btn {
|
display: flex;
|
margin-left: 5px;
|
cursor: pointer;
|
|
svg {
|
width: 16px;
|
height: 16px;
|
}
|
}
|
|
.organize-tree {
|
margin-right: 0;
|
border-right: 1px solid var(--border-color-base);
|
border-top-right-radius: 0;
|
border-bottom-right-radius: 0;
|
}
|
|
.position-tree {
|
border-top-left-radius: 0;
|
border-bottom-left-radius: 0;
|
}
|
|
.organize-tree-advanced {
|
width: 440px;
|
margin-right: 10px;
|
border-right: unset;
|
border-top-right-radius: var(--radius);
|
border-bottom-right-radius: var(--radius);
|
}
|
</style>
|