pull/5677/head
Cagatay Civici 2024-04-29 12:57:19 +03:00
commit b409cf5e2f
9 changed files with 323 additions and 83 deletions

View File

@ -278,10 +278,26 @@ export default {
type: Object,
default() {
return {
addRule: { severity: 'info', text: true, size: 'small' },
removeRule: { severity: 'danger', text: true, size: 'small' },
apply: { size: 'small' },
clear: { outlined: true, size: 'small' }
filter: { severity: 'secondary', text: true, rounded: true },
inline: {
clear: { severity: 'secondary', text: true, rounded: true }
},
popover: {
addRule: { severity: 'info', text: true, size: 'small' },
removeRule: { severity: 'danger', text: true, size: 'small' },
apply: { size: 'small' },
clear: { outlined: true, size: 'small' }
}
};
}
},
editButtonProps: {
type: Object,
default() {
return {
init: { severity: 'secondary', text: true, rounded: true },
save: { severity: 'secondary', text: true, rounded: true },
cancel: { severity: 'secondary', text: true, rounded: true }
};
}
}

View File

@ -83,15 +83,45 @@
</button>
</template>
<template v-else-if="editMode === 'row' && columnProp('rowEditor')">
<button v-if="!d_editing" v-ripple :class="cx('rowEditorInitButton')" type="button" :aria-label="initButtonAriaLabel" @click="onRowEditInit" v-bind="getColumnPT('rowEditorInitButton')" data-pc-group-section="rowactionbutton">
<component :is="(column.children && column.children.roweditoriniticon) || 'PencilIcon'" :class="cx('rowEditorInitIcon')" v-bind="getColumnPT('rowEditorInitIcon')" />
</button>
<button v-if="d_editing" v-ripple :class="cx('rowEditorSaveButton')" type="button" :aria-label="saveButtonAriaLabel" @click="onRowEditSave" v-bind="getColumnPT('rowEditorSaveButton')" data-pc-group-section="rowactionbutton">
<component :is="(column.children && column.children.roweditorsaveicon) || 'CheckIcon'" :class="cx('rowEditorSaveIcon')" v-bind="getColumnPT('rowEditorSaveIcon')" />
</button>
<button v-if="d_editing" v-ripple :class="cx('rowEditorCancelButton')" type="button" :aria-label="cancelButtonAriaLabel" @click="onRowEditCancel" v-bind="getColumnPT('rowEditorCancelButton')" data-pc-group-section="rowactionbutton">
<component :is="(column.children && column.children.roweditorcancelicon) || 'TimesIcon'" :class="cx('rowEditorCancelIcon')" v-bind="getColumnPT('rowEditorCancelIcon')" />
</button>
<Button
v-if="!d_editing"
:class="cx('rowEditorInitButton')"
:aria-label="initButtonAriaLabel"
:unstyled="unstyled"
@click="onRowEditInit"
v-bind="{ ...getColumnPT('rowEditorInitButton'), ...editButtonProps.init }"
data-pc-group-section="rowactionbutton"
>
<template #icon="slotProps">
<component :is="(column.children && column.children.roweditoriniticon) || 'PencilIcon'" :class="[cx('rowEditorInitIcon'), slotProps.class]" v-bind="getColumnPT('rowEditorInitIcon')" />
</template>
</Button>
<Button
v-if="d_editing"
:class="cx('rowEditorSaveButton')"
:aria-label="saveButtonAriaLabel"
:unstyled="unstyled"
@click="onRowEditSave"
v-bind="{ ...getColumnPT('rowEditorSaveButton'), ...editButtonProps.save }"
data-pc-group-section="rowactionbutton"
>
<template #icon="slotProps">
<component :is="(column.children && column.children.roweditorsaveicon) || 'CheckIcon'" :class="[cx('rowEditorSaveIcon'), slotProps.class]" v-bind="getColumnPT('rowEditorSaveIcon')" />
</template>
</Button>
<Button
v-if="d_editing"
:class="cx('rowEditorCancelButton')"
:aria-label="cancelButtonAriaLabel"
:unstyled="unstyled"
@click="onRowEditCancel"
v-bind="{ ...getColumnPT('rowEditorCancelButton'), ...editButtonProps.cancel }"
data-pc-group-section="rowactionbutton"
>
<template #icon="slotProps">
<component :is="(column.children && column.children.roweditorcancelicon) || 'TimesIcon'" :class="[cx('rowEditorCancelIcon'), slotProps.class]" v-bind="getColumnPT('rowEditorCancelIcon')" />
</template>
</Button>
</template>
<template v-else>{{ resolveFieldData() }}</template>
</td>
@ -99,6 +129,7 @@
<script>
import BaseComponent from 'primevue/basecomponent';
import Button from 'primevue/button';
import BarsIcon from 'primevue/icons/bars';
import CheckIcon from 'primevue/icons/check';
import ChevronDownIcon from 'primevue/icons/chevrondown';
@ -181,6 +212,10 @@ export default {
collapsedRowIcon: {
type: String,
default: null
},
editButtonProps: {
type: Object,
default: null
}
},
documentEditListener: null,
@ -532,12 +567,13 @@ export default {
components: {
DTRadioButton: RowRadioButton,
DTCheckbox: RowCheckbox,
ChevronDownIcon: ChevronDownIcon,
ChevronRightIcon: ChevronRightIcon,
BarsIcon: BarsIcon,
PencilIcon: PencilIcon,
CheckIcon: CheckIcon,
TimesIcon: TimesIcon
Button,
ChevronDownIcon,
ChevronRightIcon,
BarsIcon,
PencilIcon,
CheckIcon,
TimesIcon
},
directives: {
ripple: Ripple

View File

@ -59,6 +59,7 @@
:isRowExpanded="d_rowExpanded"
:expandedRowIcon="expandedRowIcon"
:collapsedRowIcon="collapsedRowIcon"
:editButtonProps="editButtonProps"
@radio-change="onRadioChange"
@checkbox-change="onCheckboxChange"
@row-toggle="onRowToggle"
@ -253,6 +254,10 @@ export default {
type: String,
default: 'stack'
},
editButtonProps: {
type: Object,
default: null
},
virtualScrollerContentProps: {
type: Object,
default: null

View File

@ -3,24 +3,34 @@
<div v-if="display === 'row'" :class="cx('filterInput')" v-bind="{ ...filterInputProps, ...getColumnPT('filterInput') }">
<component :is="filterElement" :field="field" :filterModel="filters[field]" :filterCallback="filterCallback" />
</div>
<button
<Button
v-if="showMenuButton"
ref="icon"
type="button"
:aria-label="filterMenuButtonAriaLabel"
aria-haspopup="true"
:aria-expanded="overlayVisible"
:aria-controls="overlayId"
:class="cx('filterMenuButton')"
:unstyled="unstyled"
@click="toggleMenu($event)"
@keydown="onToggleButtonKeyDown($event)"
v-bind="getColumnPT('filterMenuButton', ptmFilterMenuParams)"
v-bind="{ ...getColumnPT('filterMenuButton', ptmFilterMenuParams), ...filterButtonProps.filter }"
>
<component :is="filterIconTemplate || 'FilterIcon'" v-bind="getColumnPT('filterMenuIcon')" />
</button>
<button v-if="showClearButton && display === 'row'" :class="cx('headerFilterClearButton')" type="button" @click="clearFilter()" v-bind="getColumnPT('headerFilterClearButton', ptmHeaderFilterClearParams)">
<component :is="filterClearIconTemplate || 'FilterSlashIcon'" v-bind="getColumnPT('filterClearIcon')" />
</button>
<template #icon="slotProps">
<component :is="filterIconTemplate || 'FilterIcon'" :class="slotProps.class" v-bind="getColumnPT('filterMenuIcon')" />
</template>
</Button>
<Button
v-if="showClearButton && display === 'row' && hasRowFilter()"
:class="cx('headerFilterClearButton')"
:unstyled="unstyled"
@click="clearFilter()"
v-bind="{ ...getColumnPT('headerFilterClearButton', ptmHeaderFilterClearParams), ...filterButtonProps.inline.clear }"
>
<template #icon="slotProps">
<component :is="filterClearIconTemplate || 'FilterSlashIcon'" :class="slotProps.class" v-bind="getColumnPT('filterClearIcon')" />
</template>
</Button>
<Portal>
<transition name="p-connected-overlay" @enter="onOverlayEnter" @after-enter="onOverlayAfterEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave" v-bind="getColumnPT('transition')">
<div
@ -59,7 +69,7 @@
</template>
<template v-else>
<div v-if="isShowOperator" :class="cx('filterOperator')" v-bind="getColumnPT('filterOperator')">
<CFSelect
<Select
:options="operatorOptions"
:modelValue="operator"
:aria-label="filterOperatorAriaLabel"
@ -69,11 +79,11 @@
@update:modelValue="onOperatorChange($event)"
:unstyled="unstyled"
:pt="getColumnPT('filterOperatorDropdown')"
></CFSelect>
></Select>
</div>
<div :class="cx('filterConstraints')" v-bind="getColumnPT('filterConstraints')">
<div v-for="(fieldConstraint, i) of fieldConstraints" :key="i" :class="cx('filterConstraint')" v-bind="getColumnPT('filterConstraint')">
<CFSelect
<Select
v-if="isShowMatchModes"
:options="matchModes"
:modelValue="fieldConstraint.matchMode"
@ -84,65 +94,65 @@
@update:modelValue="onMenuMatchModeChange($event, i)"
:unstyled="unstyled"
:pt="getColumnPT('filterMatchModeDropdown')"
></CFSelect>
></Select>
<component v-if="display === 'menu'" :is="filterElement" :field="field" :filterModel="fieldConstraint" :filterCallback="filterCallback" :applyFilter="applyFilter" />
<div v-bind="getColumnPT('filterRemove')">
<CFButton
<Button
v-if="showRemoveIcon"
type="button"
:class="cx('filterRemoveButton')"
@click="removeConstraint(i)"
:label="removeRuleButtonLabel"
:unstyled="unstyled"
v-bind="filterButtonProps.removeRule"
v-bind="filterButtonProps.popover.removeRule"
:pt="getColumnPT('filterRemoveButton')"
>
<template #icon="iconProps">
<component :is="filterRemoveIconTemplate || 'TrashIcon'" :class="iconProps.class" v-bind="getColumnPT('filterRemoveButton')['icon']" />
</template>
</CFButton>
</Button>
</div>
</div>
</div>
<div v-if="isShowAddConstraint" :class="cx('filterAddRule')" v-bind="getColumnPT('filterAddRule')">
<CFButton
<Button
type="button"
:label="addRuleButtonLabel"
iconPos="left"
:class="cx('filterAddRuleButton')"
@click="addConstraint()"
:unstyled="unstyled"
v-bind="filterButtonProps.addRule"
v-bind="filterButtonProps.popover.addRule"
:pt="getColumnPT('filterAddRuleButton')"
>
<template #icon="iconProps">
<component :is="filterAddIconTemplate || 'PlusIcon'" :class="iconProps.class" v-bind="getColumnPT('filterAddRuleButton')['icon']" />
</template>
</CFButton>
</Button>
</div>
<div :class="cx('filterButtonbar')" v-bind="getColumnPT('filterButtonbar')">
<CFButton
<Button
v-if="!filterClearTemplate && showClearButton"
type="button"
:class="cx('filterClearButton')"
:label="clearButtonLabel"
@click="clearFilter"
:unstyled="unstyled"
v-bind="filterButtonProps.clear"
v-bind="filterButtonProps.popover.clear"
:pt="getColumnPT('filterClearButton')"
></CFButton>
></Button>
<component v-else :is="filterClearTemplate" :field="field" :filterModel="filters[field]" :filterCallback="clearFilter" />
<template v-if="showApplyButton">
<CFButton
<Button
v-if="!filterApplyTemplate"
type="button"
:class="cx('filterApplyButton')"
:label="applyButtonLabel"
@click="applyFilter()"
:unstyled="unstyled"
v-bind="filterButtonProps.apply"
v-bind="filterButtonProps.popover.apply"
:pt="getColumnPT('filterApplyButton')"
></CFButton>
></Button>
<component v-else :is="filterApplyTemplate" :field="field" :filterModel="filters[field]" :filterCallback="applyFilter" />
</template>
</div>
@ -518,7 +528,7 @@ export default {
hide() {
this.overlayVisible = false;
DomHandler.focus(this.$refs.icon);
DomHandler.focus(this.$refs.icon.$el);
},
onContentClick(event) {
this.selfClick = true;
@ -538,7 +548,7 @@ export default {
ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
DomHandler.addStyles(el, { position: 'absolute', top: '0', left: '0' });
DomHandler.absolutePosition(this.overlay, this.$refs.icon);
DomHandler.absolutePosition(this.overlay, this.$refs.icon.$el);
this.bindOutsideClickListener();
this.bindScrollListener();
this.bindResizeListener();
@ -575,7 +585,7 @@ export default {
return !this.isTargetClicked(target) && this.overlay && !(this.overlay.isSameNode(target) || this.overlay.contains(target));
},
isTargetClicked(target) {
return this.$refs.icon && (this.$refs.icon.isSameNode(target) || this.$refs.icon.contains(target));
return this.$refs.icon && (this.$refs.icon.$el.isSameNode(target) || this.$refs.icon.$el.contains(target));
},
bindOutsideClickListener() {
if (!this.outsideClickListener) {
@ -599,7 +609,7 @@ export default {
},
bindScrollListener() {
if (!this.scrollHandler) {
this.scrollHandler = new ConnectedOverlayScrollHandler(this.$refs.icon, () => {
this.scrollHandler = new ConnectedOverlayScrollHandler(this.$refs.icon.$el, () => {
if (this.overlayVisible) {
this.hide();
}
@ -711,13 +721,13 @@ export default {
}
},
components: {
CFSelect: Select,
CFButton: Button,
Portal: Portal,
FilterSlashIcon: FilterSlashIcon,
FilterIcon: FilterIcon,
TrashIcon: TrashIcon,
PlusIcon: PlusIcon
Select,
Button,
Portal,
FilterSlashIcon,
FilterIcon,
TrashIcon,
PlusIcon
},
directives: {
focustrap: FocusTrap

View File

@ -161,9 +161,19 @@ export interface DataTableExportCSVOptions {
}
/**
* Custom datatable filter button props options.
* Custom datatable filter inline button props options.
*/
export interface DataTableFilterButtonPropsOptions {
export interface DataTableFilterButtonInlinePropsOptions {
/**
* Apply button props
*/
clear: ButtonProps | undefined;
}
/**
* Custom datatable filter popover button props options.
*/
export interface DataTableFilterButtonPopoverPropsOptions {
/**
* Add rule button props
*/
@ -182,6 +192,42 @@ export interface DataTableFilterButtonPropsOptions {
clear: ButtonProps | undefined;
}
/**
* Custom datatable filter buttons' props options.
*/
export interface DataTableFilterButtonPropsOptions {
/**
* Filter button props
*/
filter: ButtonProps | undefined;
/**
* Inline filter buttons' options
*/
inline: DataTableFilterButtonInlinePropsOptions | undefined;
/**
* Popover filter buttons' options
*/
popover: DataTableFilterButtonPopoverPropsOptions | undefined;
}
/**
* Custom datatable edit buttons' props options.
*/
export interface DataTableEditButtonPropsOptions {
/**
* Init button props
*/
init: ButtonProps | undefined;
/**
* Save button props
*/
save: ButtonProps | undefined;
/**
* Cancel button props
*/
cancel: ButtonProps | undefined;
}
/**
* Custom sort event.
* @see {@link DataTableEmits.sort}
@ -1156,13 +1202,28 @@ export interface DataTableProps {
/**
* Used to pass all filter button property object
* @defaultValue {
addRule: { severity: 'info', text: true, size: 'small' },
removeRule: { severity: 'danger', text: true, size: 'small' },
apply: { size: 'small' },
clear: { outlined: true, size: 'small' }
filter: { severity: 'secondary', text: true, rounded: true },
inline: {
clear: { severity: 'secondary', text: true, rounded: true }
},
popover: {
addRule: { severity: 'info', text: true, size: 'small' },
removeRule: { severity: 'danger', text: true, size: 'small' },
apply: { size: 'small' },
clear: { outlined: true, size: 'small' }
}
}
*/
filterButtonProps?: DataTableFilterButtonPropsOptions | undefined;
/**
* Used to pass all edit button property object
* @defaultValue {
init: { severity: 'secondary', text: true, rounded: true },
save: { severity: 'secondary', text: true, rounded: true },
cancel: { severity: 'secondary', text: true, rounded: true }
}
*/
editButtonProps?: DataTableEditButtonPropsOptions | undefined;
/**
* It generates scoped CSS variables using design tokens for the component.
*/

View File

@ -131,6 +131,7 @@
:editingRowKeys="d_editingRowKeys"
:templates="$slots"
:responsiveLayout="responsiveLayout"
:editButtonProps="rowEditButtonProps"
:isVirtualScrollerDisabled="true"
@rowgroup-toggle="toggleRowGroup"
@row-click="onRowClick($event)"
@ -187,6 +188,7 @@
:editingRowKeys="d_editingRowKeys"
:templates="$slots"
:responsiveLayout="responsiveLayout"
:editButtonProps="rowEditButtonProps"
:virtualScrollerContentProps="slotProps"
:isVirtualScrollerDisabled="virtualScrollerDisabled"
@rowgroup-toggle="toggleRowGroup"
@ -2072,13 +2074,29 @@ export default {
},
headerFilterButtonProps() {
return {
...{
filter: { severity: 'secondary', text: true, rounded: true },
...this.filterButtonProps,
inline: {
clear: { severity: 'secondary', text: true, rounded: true },
...this.filterButtonProps.inline
},
popover: {
addRule: { severity: 'info', text: true, size: 'small' },
removeRule: { severity: 'danger', text: true, size: 'small' },
apply: { size: 'small' },
clear: { outlined: true, size: 'small' }
clear: { outlined: true, size: 'small' },
...this.filterButtonProps.popover
}
};
},
rowEditButtonProps() {
return {
...{
init: { severity: 'secondary', text: true, rounded: true },
save: { severity: 'secondary', text: true, rounded: true },
cancel: { severity: 'secondary', text: true, rounded: true }
},
...this.filterButtonProps
...this.editButtonProps
};
},
virtualScrollerDisabled() {

View File

@ -31,6 +31,7 @@
:editingRows="editingRows"
:editingRowKeys="editingRowKeys"
:templates="templates"
:editButtonProps="editButtonProps"
:responsiveLayout="responsiveLayout"
:virtualScrollerContentProps="virtualScrollerContentProps"
:isVirtualScrollerDisabled="isVirtualScrollerDisabled"
@ -211,6 +212,10 @@ export default {
type: Boolean,
default: false
},
editButtonProps: {
type: Object,
default: null
},
responsiveLayout: {
type: String,
default: 'stack'

View File

@ -16185,7 +16185,9 @@
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<CalendarPassThroughOptions>",
"default": ""
"default": "",
"description": "",
"deprecated": "since v4. Use the new structure of DatePicker instead."
},
{
"name": "card",
@ -16234,7 +16236,9 @@
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<ChipsPassThroughOptions>",
"default": ""
"default": "",
"description": "",
"deprecated": "since v4. Use the new structure of InputChips instead."
},
{
"name": "colorpicker",
@ -16339,7 +16343,9 @@
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<DropdownPassThroughOptions<any>>",
"default": ""
"default": "",
"description": "",
"deprecated": "since v4. Use the new structure of Select instead."
},
{
"name": "dynamicdialog",
@ -16423,7 +16429,9 @@
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<InputSwitchPassThroughOptions>",
"default": ""
"default": "",
"description": "",
"deprecated": "since v4. Use the new structure of ToggleSwitch instead."
},
{
"name": "inputtext",
@ -16500,7 +16508,9 @@
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<OverlayPanelPassThroughOptions>",
"default": ""
"default": "",
"description": "",
"deprecated": "since v4. Use the new structure of Popover instead."
},
{
"name": "paginator",
@ -16598,7 +16608,9 @@
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<SidebarPassThroughOptions>",
"default": ""
"default": "",
"description": "",
"deprecated": "since v4. Use the new structure of Drawer instead."
},
{
"name": "skeleton",
@ -19652,8 +19664,23 @@
],
"methods": []
},
"DataTableFilterButtonPropsOptions": {
"description": "Custom datatable filter button props options.",
"DataTableFilterButtonInlinePropsOptions": {
"description": "Custom datatable filter inline button props options.",
"relatedProp": "",
"props": [
{
"name": "clear",
"optional": false,
"readonly": false,
"type": "undefined | ButtonProps",
"default": "",
"description": "Apply button props"
}
],
"methods": []
},
"DataTableFilterButtonPopoverPropsOptions": {
"description": "Custom datatable filter popover button props options.",
"relatedProp": "",
"props": [
{
@ -19691,6 +19718,68 @@
],
"methods": []
},
"DataTableFilterButtonPropsOptions": {
"description": "Custom datatable filter buttons' props options.",
"relatedProp": "",
"props": [
{
"name": "filter",
"optional": false,
"readonly": false,
"type": "undefined | ButtonProps",
"default": "",
"description": "Filter button props"
},
{
"name": "inline",
"optional": false,
"readonly": false,
"type": "undefined | DataTableFilterButtonInlinePropsOptions",
"default": "",
"description": "Inline filter buttons' options"
},
{
"name": "popover",
"optional": false,
"readonly": false,
"type": "undefined | DataTableFilterButtonPopoverPropsOptions",
"default": "",
"description": "Popover filter buttons' options"
}
],
"methods": []
},
"DataTableEditButtonPropsOptions": {
"description": "Custom datatable edit buttons' props options.",
"relatedProp": "",
"props": [
{
"name": "init",
"optional": false,
"readonly": false,
"type": "undefined | ButtonProps",
"default": "",
"description": "Init button props"
},
{
"name": "save",
"optional": false,
"readonly": false,
"type": "undefined | ButtonProps",
"default": "",
"description": "Save button props"
},
{
"name": "cancel",
"optional": false,
"readonly": false,
"type": "undefined | ButtonProps",
"default": "",
"description": "Cancel button props"
}
],
"methods": []
},
"DataTableSortEvent": {
"description": "Custom sort event.",
"relatedProp": "DataTableEmits.sort",
@ -21681,6 +21770,14 @@
"default": "",
"description": "Used to pass all filter button property object"
},
{
"name": "editButtonProps",
"optional": true,
"readonly": false,
"type": "DataTableEditButtonPropsOptions",
"default": "",
"description": "Used to pass all edit button property object"
},
{
"name": "dt",
"optional": true,
@ -59271,14 +59368,6 @@
"default": "false",
"description": "When enabled, hidden tabs are not rendered at all. Defaults to false that hides tabs with css."
},
{
"name": "orientation",
"optional": true,
"readonly": false,
"type": "\"horizontal\" | \"vertical\"",
"default": "horizontal",
"description": "Specifies the layout of the component, valid values are 'horizontal' and 'vertical'."
},
{
"name": "scrollable",
"optional": true,

View File

@ -17,7 +17,7 @@
table: { style: 'min-width: 50rem' },
column: {
bodycell: ({ state }) => ({
style: state['d_editing'] && 'padding-top: 0.6rem; padding-bottom: 0.6rem'
style: state['d_editing'] && 'padding-top: 0.75rem; padding-bottom: 0.75rem'
})
}
}"
@ -79,7 +79,7 @@ export default {
table: { style: 'min-width: 50rem' },
column: {
bodycell: ({ state }) => ({
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
style: state['d_editing']&&'padding-top: 0.75rem; padding-bottom: 0.75rem'
})
}
}"
@ -125,7 +125,7 @@ export default {
table: { style: 'min-width: 50rem' },
column: {
bodycell: ({ state }) => ({
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
style: state['d_editing']&&'padding-top: 0.75rem; padding-bottom: 0.75rem'
})
}
}"
@ -219,7 +219,7 @@ export default {
table: { style: 'min-width: 50rem' },
column: {
bodycell: ({ state }) => ({
style: state['d_editing']&&'padding-top: 0.6rem; padding-bottom: 0.6rem'
style: state['d_editing']&&'padding-top: 0.75rem; padding-bottom: 0.75rem'
})
}
}"