Skip to content

Commit

Permalink
feat: cv-data-table add property to force showing batch actions
Browse files Browse the repository at this point in the history
  • Loading branch information
davidnixon committed Mar 31, 2024
1 parent b01cf04 commit 64cbe0c
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 126 deletions.
75 changes: 26 additions & 49 deletions src/components/CvDataTable/CvDataTable.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import CvDataTableCell from "./CvDataTableCell.vue";
import CvDataTableAction from "./CvDataTableAction.vue";
import CvDataTableSkeleton from "./CvDataTableSkeleton.vue";
import CvButton from '../CvButton/CvButton.vue'
import { sbCompPrefix } from '../../global/storybook-utils';
import { sbCompPrefix, storySourceCode } from '../../global/storybook-utils';
import { action } from '@storybook/addon-actions';
import { Terminal16 as CompileIcon, Debug16 as DebugIcon, Chip16 as EmbedIcon,
TrashCan16 as TrashCanIcon} from '@carbon/icons-vue'
Expand Down Expand Up @@ -76,27 +76,26 @@ setup() {
skeletonCols: args.skeletonCols,
skeletonTitle: args.title,
skeletonHelper: args.helperText,
testData
testData,
};
},
// And then the `args` are bound to your component with `v-bind="args"`
template: args.template,
});
const defaultTemplate = `
<cv-data-table
<cv-data-table v-bind="args"
@search="onSearch"
@sort="onSort"
@row-select-change="onRowSelectChange"
@row-select-changes="onRowSelectChanges"
@overflow-menu-click="onOverflowMenuClick"
@row-expanded="onRowExpanded"
@pagination="onPagination"
v-bind="args"
>
<template v-if="useBatchActions" v-slot:batch-actions>
<template v-if="useBatchActions" #batch-actions>
<cv-button :icon="trashIcon" @click="onDelete">Delete</cv-button>
</template>
<template v-if="useActions" v-slot:actions>
<template v-if="useActions" #actions>
<cv-data-table-action @click="onAction1" aria-label="compile" alt="compile">
<compile-icon>
<title>Compile</title>
Expand Down Expand Up @@ -142,6 +141,16 @@ const skeletonTemplate = `
:rows="skeletonRows"
:title="skeletonTitle"
:helperText="skeletonHelper">
<template v-if="useBatchActions" #batch-actions>
<cv-button :icon="trashIcon" @click="onDelete">Delete</cv-button>
</template>
<template v-if="useActions" #actions>
<cv-data-table-action @click="onAction1" aria-label="compile" alt="compile">
<compile-icon>
<title>Compile</title>
</compile-icon>
</cv-data-table-action>
</template>
</cv-data-table-skeleton>
`;

Expand Down Expand Up @@ -184,6 +193,8 @@ completion for it. See [discussion](https://github.com/vuejs/core/issues/3432) f
- The Vue 3 implementation uses an internal store to manage the state of the table. You can see updates
to the state by setting the debug variable in the local storage. `localStorage.debug="cv:data-table-store"`
and then reloading the page.
- If you were using something like `this.$refs.tableEditPath.batchActive = true` to force batch actions to show even
when no items were select, please now use the new property `stickyBatchActive`.

<Canvas>
<Story
Expand All @@ -206,9 +217,10 @@ and then reloading the page.
'items-selected',
'of-n-pages',
'range-text',
'skeleton'
'skeleton',
'update:rowsSelected',
] },
docs: { source: { code: defaultTemplate.replace('v-bind="args"', '') } },
docs: { source: { code: storySourceCode(defaultTemplate, Template.args) } },
}}
args={{
template: defaultTemplate,
Expand Down Expand Up @@ -248,8 +260,9 @@ and then reloading the page.
'of-n-pages',
'range-text',
'skeleton',
'update:rowsSelected',
] },
docs: { source: { code: expandingRowsTemplate.replace('v-bind="args"', '') } },
docs: { source: { code: storySourceCode(expandingRowsTemplate, Template.args) } },
}}
args={{
template: expandingRowsTemplate,
Expand All @@ -273,53 +286,17 @@ and then reloading the page.
<Story
name="Skeleton"
parameters={{
controls: { exclude: [
'template',
'actionBarAriaLabel',
'autoWidth',
'batchCancelLabel',
'borderless',
'collapseAllAriaLabel',
'expandAllAriaLabel',
'expandingSearch',
'hasExpandAll',
'initialSearchValue',
'overflowMenu',
'rowSize',
'rowsSelected',
'searchClearLabel',
'searchLabel',
'searchPlaceholder',
'selectAllAriaLabel',
'skeleton',
'sortable',
'staticWidth',
'stickyHeader',
'zebra',
'overflow-menu-click',
'pagination',
'row-expanded',
'actions',
'batch-actions',
'data',
'headings',
'row-select-change',
'row-select-changes',
'sort',
'helper-text',
'items-selected',
'of-n-pages',
'range-text',
'columns'
] },
docs: { source: { code: skeletonTemplate.replace('v-bind="args"', '') } },
controls: { include: [ 'skeletonCols', 'skeletonRows', 'title', 'helperText', 'useBatchActions', 'useActions'] },
docs: { source: { code: storySourceCode(skeletonTemplate, Template.args) } },
}}
args={{
template: skeletonTemplate,
title: 'Table title',
helperText: 'Data has been requested...',
skeletonRows: 5,
skeletonCols: 5,
useBatchActions: false,
useActions: false
}}
argTypes={{
}}
Expand Down
90 changes: 45 additions & 45 deletions src/components/CvDataTable/CvDataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@
v-if="hasBatchActions"
:class="`${carbonPrefix}--table-column-checkbox`"
>
<cv-checkbox-skeleton v-if="isSkeleton" />
<cv-checkbox
v-else
v-model="headingChecked"
:form-item="false"
value="headingCheck"
Expand Down Expand Up @@ -229,7 +231,7 @@ import CvDataTableHeading from './CvDataTableHeading.vue';
import CvDataTableRow from './CvDataTableRow.vue';
import CvDataTableCell from './CvDataTableCell.vue';
import CvButton from '../CvButton';
import CvCheckbox from '../CvCheckbox';
import { CvCheckbox, CvCheckboxSkeleton } from '../CvCheckbox';
import CvPagination from '../CvPagination';
import Search16 from '@carbon/icons-vue/es/search/16';
import Close16 from '@carbon/icons-vue/es/close/16';
Expand All @@ -254,37 +256,31 @@ import store from './cvDataTableStore';
import Empty from '../CvEmpty/_CvEmpty.vue';
const props = defineProps({
/** Arial label for the action bar. */
actionBarAriaLabel: { type: String, default: 'Table Action Bar' },
/** Arial label for the "collapse all" button in tables with expandable rows". */
collapseAllAriaLabel: { type: String, default: 'Collapse all rows' },
/** Arial label for the "expand all" button in tables with expandable rows". */
expandAllAriaLabel: { type: String, default: 'Expand all rows' },
/** Arial label for the "select all" button in tables with selectable rows". */
selectAllAriaLabel: { type: String, default: 'Select all rows' },
/**
* Table will size use auto sizing
*/
/** Table will size use auto sizing */
autoWidth: { type: Boolean, default: false },
/**
* Label for the button to cancel batch actions
*/
/** Label for the button to cancel batch actions */
batchCancelLabel: { type: String, default: 'Cancel' },
/**
* Table will have no border
*/
/** Table will have no border */
borderless: { type: Boolean, default: false },
/**
* An array of overflow menu labels. On click CvDataTable will raise an 'overflow-menu-click' event passing an object containing menuIndex, menuLabel and rowValue
* - As part of the array pass an object containing props for the overflowMenu. E.g. { label: 'Overflow menu', tipAlignment: 'end', tipPosition: 'top' },
*/
overflowMenu: { type: [Boolean, Array], default: () => [] },
/**
* can be set to true or an object containing camel case props for a CvPagination component
*/
/** can be set to true or an object containing camel case props for a CvPagination component */
pagination: {
type: [Boolean, Object],
default: false,
},
/**
* 'compact', 'small', or 'tall'
*/
/** 'compact', 'small', or 'tall' */
rowSize: {
type: String,
default: 'lg',
Expand All @@ -310,13 +306,9 @@ const props = defineProps({
searchLabel: { type: String, default: 'Search' },
searchPlaceholder: { type: String, default: 'Search' },
searchClearLabel: { type: String, default: 'Clear search' },
/**
* Set text in search bar on table generation
*/
/** Set text in search bar on table generation */
initialSearchValue: { type: String, default: '' },
/**
* can be sorted
*/
/** can be sorted */
sortable: { type: Boolean, default: false },
/** Table will have expandable rows */
expandable: { type: Boolean, default: false },
Expand All @@ -331,35 +323,39 @@ const props = defineProps({
* - Optionally a sortable property - if any column sets this to true then only columns with sortable set to true are sortable. NOTE: table sortable property not required.
*/
columns: { type: Array, default: () => [] },
/**
* Two-dimensional array of strings.
*/
/** Two-dimensional array of strings. */
data: { type: Array, default: () => [] },
/**
* the table striped
*/
/** `true` to use Zebra style striping. */
zebra: { type: Boolean, default: false },
/**
* Specify whether the header should be sticky. Still experimental: may not work with every combination of table props.
*/
/** Specify whether the header should be sticky. Still experimental: may not work with every combination of table props. */
stickyHeader: { type: Boolean, default: false },
/**
* An array containing the selected row values. Supports v-model via the row-select-changes event.
*/
/** An array containing the selected row values. Supports v-model via the row-select-changes event. */
rowsSelected: { type: Array, default: () => [] },
/** Normally batch actions are hidden if no items are selected. Set this to true to always show batch actions */
stickyBatchActive: { type: Boolean, default: false },
/** subtext on the table */
helperText: { type: String, default: undefined },
/** Animate the search bar opening */
expandingSearch: { type: Boolean, default: true },
/** Show table loading / skeleton state */
skeleton: { type: Boolean, default: false },
/** Should the expand all button be available */
hasExpandAll: { type: Boolean, default: false },
/**
* Use a width of 'auto' instead of 100%
*/
/** Use a width of 'auto' instead of 100% */
staticWidth: { type: Boolean, default: false },
/** User defined search action */
onSearch: { type: Function, default: undefined },
...propsCvId,
});
const uid = useCvId(props, true);
const isSkeleton = ref(props.skeleton);
provide('is-skeleton', isSkeleton);
watch(
() => props.skeleton,
() => (isSkeleton.value = props.skeleton)
);
let bus = undefined;
onBeforeMount(() => {
bus = getBus(uid.value);
Expand Down Expand Up @@ -419,12 +415,12 @@ onUpdated(checkSlots);
const hasActions = ref(false);
const hasToolbar = ref(false);
const hasBatchActions = computed(() => {
return store.hasBatchActions(uid);
});
const hasBatchActions = ref(false);
provide('has-batch-actions', hasBatchActions);
function checkSlots() {
// NOTE: slots is not reactive so needs to be managed on updated
store.setBatchActions(uid, !!slots['batch-actions']);
hasBatchActions.value = !!slots['batch-actions'];
hasActions.value = !!slots.actions;
hasToolbar.value = !!(
slots.actions ||
Expand Down Expand Up @@ -531,7 +527,14 @@ function checkSearchExpand(force) {
}
const dataRowsSelected = ref(props.rowsSelected);
const batchActive = ref(false);
const batchActive = computed(() => {
return (
props.stickyBatchActive ||
dataRowsSelected.value.length > 0 ||
headingChecked.value
);
});
const headingChecked = ref(false);
watch(
Expand All @@ -555,7 +558,6 @@ function updateRowsSelected() {
}
}
headingChecked.value = dataRowsSelected.value.length === rows.length;
batchActive.value = dataRowsSelected.value.length > 0;
}
const emit = defineEmits([
Expand All @@ -581,7 +583,6 @@ function onClearClick() {
}
function onHeadingCheckChange() {
// check /uncheck all children
batchActive.value = headingChecked.value;
dataRowsSelected.value = [];
const rows = store.rows(uid);
for (const child of rows) {
Expand Down Expand Up @@ -617,7 +618,6 @@ function onRowCheckChange(payload) {
dataRowsSelected.value = Array.from(modelSet);
const rows = store.rows(uid);
headingChecked.value = dataRowsSelected.value.length === rows.length;
batchActive.value = dataRowsSelected.value.length > 0;
emit('row-select-change', { value, selected: checked });
emit('row-select-changes', dataRowsSelected.value);
Expand Down
11 changes: 6 additions & 5 deletions src/components/CvDataTable/_CvDataTableRowInner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
v-if="hasBatchActions"
:class="`${carbonPrefix}--table-column-checkbox`"
>
<cv-checkbox-skeleton v-if="isSkeleton" />
<cv-checkbox
v-else
ref="rowChecked"
v-model="dataChecked"
:form-item="false"
Expand All @@ -35,7 +37,7 @@
:label="
ariaLabelForBatchCheckbox || `Select row ${value} for batch action`
"
hide-label
:hide-label="true"
@change="onChange"
/>
</td>
Expand All @@ -61,7 +63,7 @@

<script setup>
import { carbonPrefix } from '../../global/settings';
import CvCheckbox from '../CvCheckbox';
import { CvCheckbox, CvCheckboxSkeleton } from '../CvCheckbox';
import CvOverflowMenu from '../CvOverflowMenu';
import CvOverflowMenuItem from '../CvOverflowMenu/CvOverflowMenuItem.vue';
import ChevronRight16 from '@carbon/icons-vue/es/chevron--right/16';
Expand Down Expand Up @@ -89,6 +91,7 @@ const props = defineProps({
rowId: { type: String, default: undefined },
});
const isSkeleton = inject('is-skeleton', ref(false));
/** @type {Ref<UnwrapRef<Set<>>>} */
const expandingRowIds = inject('expanding-row-ids', ref(new Set()));
const dataSomeExpandingRows = computed(() => {
Expand Down Expand Up @@ -132,9 +135,7 @@ onMounted(() => {
bus = getBus(parent);
} else console.warn('data table not found');
});
const hasBatchActions = computed(() => {
return store.hasBatchActions(parent);
});
const hasBatchActions = inject('has-batch-actions', ref(false));
function onMenuItemClick(val) {
bus.emit('cv:click', val);
Expand Down
Loading

0 comments on commit 64cbe0c

Please sign in to comment.