@@ -32,7 +32,8 @@ const Table = {
3232 expandable: Boolean ,
3333 draggableRows: Boolean ,
3434 draggableColumns: Boolean ,
35- editable: Boolean
35+ editable: Boolean ,
36+ groupBy: String ,
3637 },
3738
3839 setup (props , { emit }) {
@@ -42,7 +43,8 @@ const Table = {
4243 const rowsPerPage = ref (props .rowsPerPage )
4344 const currentPage = ref (0 )
4445 const search = reactive ({})
45- const expanded = ref (new Set ())
46+ const expandedRows = ref (new Set ())
47+ const expandedGroups = ref (new Set ())
4648
4749 // whenever pagination props changes, update the class state accordingly
4850 // thsi way pagination settings are directly passed to props and indirectly passed to class
@@ -72,11 +74,19 @@ const Table = {
7274 }
7375
7476 const toggleExpanded = rowId => {
75- if (expanded .value .has (rowId)) {
76- expanded .value .delete (rowId)
77+ if (expandedRows .value .has (rowId)) {
78+ expandedRows .value .delete (rowId)
7779 return
7880 }
79- expanded .value .add (rowId)
81+ expandedRows .value .add (rowId)
82+ }
83+
84+ const toggleExpandedGroup = group => {
85+ if (expandedGroups .value .has (group)) {
86+ expandedGroups .value .delete (group)
87+ return
88+ }
89+ expandedGroups .value .add (group)
8090 }
8191
8292 const rootClasses = computed (() => {
@@ -92,16 +102,11 @@ const Table = {
92102 })
93103
94104 const countColumns = computed (() => {
95- return (
96- data .value .getColumns ().length +
97- (props .checkable ? 1 : 0 ) +
98- (props .expandable ? 1 : 0 )
99- )
105+ return data .value .getColumns ().length + (props .checkable ? 1 : 0 ) + (props .expandable ? 1 : 0 )
100106 })
101107
102108 const handleBackPage = () => {
103- if (currentPage .value > 0 )
104- currentPage .value -= 1
109+ if (currentPage .value > 0 ) currentPage .value -= 1
105110 }
106111
107112 const handleNextPage = () => {
@@ -117,11 +122,13 @@ const Table = {
117122 rowsPerPage,
118123 currentPage,
119124 rootClasses,
120- expanded ,
125+ expandedRows ,
121126 toggleExpanded,
127+ expandedGroups,
128+ toggleExpandedGroup,
122129 countColumns,
123130 handleBackPage,
124- handleNextPage
131+ handleNextPage,
125132 }
126133 },
127134}
@@ -180,43 +187,74 @@ export default Table
180187 />
181188 </td >
182189 </tr >
183- <template v-for =" (row , idx ) in data .rows " :key =" idx " >
184- <tr
185- :draggable =" draggableRows"
186- @dragstart =" data.onDragStartRow($event, row, idx)"
187- @drop =" data.onDropRow($event, row, idx)"
188- @dragover =" data.onDragOverRow($event, row, idx)"
189- @dragleave =" data.onDragLeaveRow($event, row, idx)"
190- :class =" { 'has-background-primary': row.selected, 'has-text-white': row.selected }"
191- >
192- <td v-if =" checkable" >
193- <v-checkbox @change =" data.toggleCheck($event, row)" />
194- </td >
195- <td v-if =" expandable" >
196- <a
197- ><v-tag @click =" toggleExpanded(row.id)" type =" is-primary" >{{
198- expanded.has(row.id) ? '&uarr ; ' : '&darr ; '
199- }}</v-tag ></a
190+ <template v-if =" ! groupBy " >
191+ <template v-for =" (row , idx ) in data .rows " :key =" idx " >
192+ <tr
193+ :draggable =" draggableRows"
194+ @dragstart =" data.onDragStartRow($event, row, idx)"
195+ @drop =" data.onDropRow($event, row, idx)"
196+ @dragover =" data.onDragOverRow($event, row, idx)"
197+ @dragleave =" data.onDragLeaveRow($event, row, idx)"
198+ :class =" { 'has-background-primary': row.selected, 'has-text-white': row.selected }"
199+ >
200+ <td v-if =" checkable" >
201+ <v-checkbox @change =" data.toggleCheck($event, row)" />
202+ </td >
203+ <td v-if =" expandable" >
204+ <a @click =" toggleExpanded(row.id)" class =" is-primary" >{{
205+ expandedRows.has(row.id) ? '&uarr ; ' : '&darr ; '
206+ }}</a >
207+ </td >
208+ <td
209+ v-for =" column in data.getColumns()"
210+ :key =" column.name"
211+ :class =" column.style"
212+ :contenteditable =" props.editable"
213+ v-on:blur =" data.editCell(row, column, $event.target.textContent)"
200214 >
201- </td >
202- <td
203- v-for =" column in data.getColumns()"
204- :key =" column.name" :class =" column.style"
205- :contenteditable =' props.editable'
206- v-on:blur =" data.editCell(row, column, $event.target.textContent)" >
207- <slot :name =" column.name" :row =" row" >
208- {{ row[column.name] }}
209- </slot >
210- </td >
211- </tr >
212- <tr class =" expansion" v-if =" expanded.has(row.id)" >
213- <td :colspan =" countColumns" >
214- <slot name =" expanded" :row =" row" />
215- </td >
216- </tr >
215+ <slot :name =" column.name" :row =" row" >
216+ {{ row[column.name] }}
217+ </slot >
218+ </td >
219+ </tr >
220+ <tr class =" expansion" v-if =" expandedRows.has(row.id)" >
221+ <td :colspan =" countColumns" >
222+ <slot name =" expanded" :row =" row" />
223+ </td >
224+ </tr >
225+ </template >
226+ </template >
227+
228+ <template v-if =" groupBy " >
229+ <template v-for =" (group , idx ) in data .groups (groupBy ) " :key =" idx " >
230+ <tr >
231+ <td :colspan =" countColumns" >
232+ <a @click =" toggleExpandedGroup(group)" class =" mr-4" >{{
233+ expandedGroups.has(group) ? '&darr ; ' : '&rarr ; '
234+ }}</a >
235+ {{ groupBy }}: <v-tag type =" is-primary" class =" mx-4" >{{ group }} </v-tag >
236+ </td >
237+ </tr >
238+ <template v-if =" expandedGroups .has (group )" >
239+ <tr v-for =" (row, idx) in data.filterRows(groupBy, group)" :key =" idx" >
240+ <td
241+ v-for =" column in data.getColumns()"
242+ :key =" column.name"
243+ :class =" column.style"
244+ :contenteditable =" props.editable"
245+ v-on:blur =" data.editCell(row, column, $event.target.textContent)"
246+ >
247+ <slot :name =" column.name" :row =" row" >
248+ {{ row[column.name] }}
249+ </slot >
250+ </td >
251+ </tr >
252+ </template >
253+ </template >
217254 </template >
218255 </tbody >
219256 </table >
257+
220258 <!-- todo: move the styles to their own scope -->
221259 <div
222260 class =" pagination-wrapper"
@@ -231,11 +269,7 @@ export default Table
231269 </v-select >
232270 <!-- using :disabled wont work, so instead the click action is conditioned and the buttons are always clickable -->
233271 <a class =" pagination-previous" @click =" handleBackPage" >Previous</a >
234- <a
235- class =" pagination-next"
236- @click =" handleNextPage"
237- >Next page</a
238- >
272+ <a class =" pagination-next" @click =" handleNextPage" >Next page</a >
239273 </div >
240274
241275 <div class =" tableFooter" >
0 commit comments