Skip to content

Commit 07bb8f3

Browse files
Added listSticky for column
1 parent 9337258 commit 07bb8f3

File tree

6 files changed

+50
-9
lines changed

6 files changed

+50
-9
lines changed

adminforth/modules/configValidator.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,11 @@ export default class ConfigValidator implements IConfigValidator {
776776
return col as AdminForthResourceColumn;
777777
})
778778

779+
// Check for multiple sticky columns
780+
if (res.columns.filter(c => c.listSticky).length > 1) {
781+
errors.push(`Resource "${res.resourceId}" has more than one listSticky column. Only one column can be sticky in the list view.`);
782+
}
783+
779784
const options: Partial<AdminForthResource['options']> = {...resInput.options, bulkActions: undefined, allowedActions: undefined};
780785

781786
options.allowedActions = this.validateAndNormalizeAllowedActions(resInput, errors);

adminforth/spa/src/components/ResourceListTable.vue

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
<tbody>
1616
<!-- table header -->
17-
<tr class="t-header sticky z-10 top-0 text-xs text-lightListTableHeadingText bg-lightListTableHeading dark:bg-darkListTableHeading dark:text-darkListTableHeadingText">
18-
<td scope="col" class="p-4">
17+
<tr class="t-header sticky z-20 top-0 text-xs text-lightListTableHeadingText bg-lightListTableHeading dark:bg-darkListTableHeading dark:text-darkListTableHeadingText">
18+
<td scope="col" class="p-4 sticky-column bg-lightListTableHeading dark:bg-darkListTableHeading">
1919
<Checkbox
2020
:modelValue="allFromThisPageChecked"
2121
:disabled="!rows || !rows.length"
@@ -25,7 +25,7 @@
2525
</Checkbox>
2626
</td>
2727

28-
<td v-for="c in columnsListed" ref="headerRefs" scope="col" class="px-2 md:px-3 lg:px-6 py-3">
28+
<td v-for="c in columnsListed" ref="headerRefs" scope="col" class="px-2 md:px-3 lg:px-6 py-3" :class="{'sticky-column bg-lightListTableHeading dark:bg-darkListTableHeading': c.listSticky}">
2929

3030
<div @click="(evt) => c.sortable && onSortButtonClick(evt, c.name)"
3131
class="flex items-center " :class="{'cursor-pointer':c.sortable}">
@@ -90,7 +90,7 @@
9090

9191
:class="{'border-b': rowI !== rows.length - 1, 'cursor-pointer': row._clickUrl !== null}"
9292
>
93-
<td class="w-4 p-4 cursor-default" @click="(e)=>e.stopPropagation()">
93+
<td class="w-4 p-4 cursor-default sticky-column bg-lightListTable dark:bg-darkListTable" @click="(e)=>e.stopPropagation()">
9494
<Checkbox
9595
:model-value="checkboxesInternal.includes(row._primaryKeyValue)"
9696
@change="(e: any)=>{addToCheckedValues(row._primaryKeyValue)}"
@@ -100,7 +100,7 @@
100100
</Checkbox>
101101
</td>
102102

103-
<td v-for="c in columnsListed" class="px-2 md:px-3 lg:px-6 py-4">
103+
<td v-for="c in columnsListed" class="px-2 md:px-3 lg:px-6 py-4" :class="{'sticky-column bg-lightListTable dark:bg-darkListTable': c.listSticky}">
104104
<!-- if c.name in listComponentsPerColumn, render it. If not, render ValueRenderer -->
105105
<component
106106
:is="c?.components?.list ? getCustomComponent(typeof c.components.list === 'string' ? { file: c.components.list } : c.components.list) : ValueRenderer"
@@ -598,4 +598,15 @@ input[type="checkbox"][disabled] {
598598
input[type="checkbox"]:not([disabled]) {
599599
@apply cursor-pointer;
600600
}
601+
td.sticky-column {
602+
@apply sticky left-0 z-10;
603+
&:not(:first-child) {
604+
@apply left-[56px];
605+
}
606+
}
607+
tr:not(:first-child):hover {
608+
td.sticky-column {
609+
@apply bg-lightListTableRowHover dark:bg-darkListTableRowHover;
610+
}
611+
}
601612
</style>

adminforth/spa/src/components/ResourceListTableVirtual.vue

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<tbody>
2020
<!-- table header -->
2121
<tr class="t-header sticky z-10 top-0 text-xs bg-lightListTableHeading dark:bg-darkListTableHeading dark:text-gray-400">
22-
<td scope="col" class="p-4">
22+
<td scope="col" class="p-4 sticky-column bg-lightListTableHeading dark:bg-darkListTableHeading">
2323
<Checkbox
2424
:modelValue="allFromThisPageChecked"
2525
:disabled="!rows || !rows.length"
@@ -29,7 +29,7 @@
2929
</Checkbox>
3030
</td>
3131

32-
<td v-for="c in columnsListed" ref="headerRefs" scope="col" class="px-2 md:px-3 lg:px-6 py-3">
32+
<td v-for="c in columnsListed" ref="headerRefs" scope="col" class="px-2 md:px-3 lg:px-6 py-3" :class="{'sticky-column bg-lightListTableHeading dark:bg-darkListTableHeading': c.listSticky}">
3333

3434
<div @click="(evt) => c.sortable && onSortButtonClick(evt, c.name)"
3535
class="flex items-center " :class="{'cursor-pointer':c.sortable}">
@@ -101,7 +101,7 @@
101101
:class="{'border-b': rowI !== visibleRows.length - 1, 'cursor-pointer': row._clickUrl !== null}"
102102
@mounted="(el: any) => updateRowHeight(`row_${row._primaryKeyValue}`, el.offsetHeight)"
103103
>
104-
<td class="w-4 p-4 cursor-default" @click="(e)=>e.stopPropagation()">
104+
<td class="w-4 p-4 cursor-default sticky-column bg-lightListTableHeading dark:bg-darkListTableHeading" @click="(e)=>e.stopPropagation()">
105105
<Checkbox
106106
:model-value="checkboxesInternal.includes(row._primaryKeyValue)"
107107
@change="(e: any)=>{addToCheckedValues(row._primaryKeyValue)}"
@@ -110,7 +110,7 @@
110110
<span class="sr-only">{{ $t('checkbox') }}</span>
111111
</Checkbox>
112112
</td>
113-
<td v-for="c in columnsListed" class="px-2 md:px-3 lg:px-6 py-4">
113+
<td v-for="c in columnsListed" class="px-2 md:px-3 lg:px-6 py-4" :class="{'sticky-column bg-lightListTable dark:bg-darkListTable': c.listSticky}">
114114
<!-- if c.name in listComponentsPerColumn, render it. If not, render ValueRenderer -->
115115
<component
116116
:is="c?.components?.list ? getCustomComponent(typeof c.components.list === 'string' ? { file: c.components.list } : c.components.list) : ValueRenderer"
@@ -733,4 +733,15 @@ input[type="checkbox"][disabled] {
733733
input[type="checkbox"]:not([disabled]) {
734734
@apply cursor-pointer;
735735
}
736+
td.sticky-column {
737+
@apply sticky left-0 z-10;
738+
&:not(:first-child) {
739+
@apply left-[56px];
740+
}
741+
}
742+
tr:not(:first-child):hover {
743+
td.sticky-column {
744+
@apply bg-lightListTableRowHover dark:bg-darkListTableRowHover;
745+
}
746+
}
736747
</style>

adminforth/types/Common.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,10 @@ export interface AdminForthResourceColumnInputCommon {
872872
*/
873873
masked?: boolean,
874874

875+
/**
876+
* Sticky position for column
877+
*/
878+
listSticky?: boolean;
875879
}
876880

877881
export interface AdminForthResourceColumnCommon extends AdminForthResourceColumnInputCommon {

dev-demo/package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev-demo/resources/apartments.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export default {
139139
},
140140
{
141141
name: "country",
142+
listSticky: true,
142143
components: {
143144
list: {
144145
file: "@/renderers/CountryFlag.vue",

0 commit comments

Comments
 (0)