[#7694] don't reset the records list pagination on record update

This commit is contained in:
Gani Georgiev
2026-05-18 19:22:51 +03:00
parent b9b0e5ae80
commit d0b2551e78
9 changed files with 73 additions and 17 deletions
+1 -1
View File
@@ -12,4 +12,4 @@ PB_DOCS_URL = "https://pocketbase.io/docs"
PB_JS_SDK_URL = "https://github.com/pocketbase/js-sdk"
PB_DART_SDK_URL = "https://github.com/pocketbase/dart-sdk"
PB_RELEASES = "https://github.com/pocketbase/pocketbase/releases"
PB_VERSION = "v0.38.1"
PB_VERSION = "v0.38.2-dev"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -13,9 +13,9 @@
<!-- prism -->
<script src="./libs/prism/prism.js" data-manual></script>
<script type="module" crossorigin src="./assets/index-_S-h6ORT.js"></script>
<script type="module" crossorigin src="./assets/index-qP-3lJAQ.js"></script>
<link rel="modulepreload" crossorigin href="./assets/pocketbase.es-B_4DUNUU.js">
<link rel="stylesheet" crossorigin href="./assets/index-DRWtZ-mO.css">
<link rel="stylesheet" crossorigin href="./assets/index-Cbzik3Gc.css">
</head>
<body>
</body>
+3 -3
View File
@@ -51,16 +51,16 @@ window.app.components.refreshButton = function(propsArg = {}) {
props.onclick(e);
}
btn.classList.add("rotate");
btn.dataset.rotate = true;
btn.addEventListener("animationend", () => {
btn.classList.remove("rotate");
btn.dataset.rotate = false;
});
// fallback
clearTimeout(refreshTimeoutId);
refreshTimeoutId = setTimeout(() => {
clearTimeout(refreshTimeoutId);
btn.classList.remove("rotate");
btn.dataset.rotate = false;
}, 500);
},
},
+9 -1
View File
@@ -14,6 +14,7 @@ export function pageCollections(route) {
const pageData = store({
reset: null,
suggestReset: false,
activeRecordIdOrModel: route.query[RECORD_QUERY_KEY]?.[0] || "",
sort: route.query[SORT_QUERY_KEY]?.[0] || "",
filter: route.query[FILTER_QUERY_KEY]?.[0] || "",
@@ -148,7 +149,7 @@ export function pageCollections(route) {
];
const documentEvents = {
"record:save": (e) => {
"record:create": (e) => {
if (e.detail.collectionId != app.store.activeCollection?.id) {
return;
}
@@ -238,6 +239,9 @@ export function pageCollections(route) {
),
app.components.refreshButton({
onclick: () => refreshRecordsList(),
className: () =>
`btn transparent circle rotate-btn ${pageData.suggestReset ? "warning" : "secondary"}`,
tooltip: () => `Refresh${pageData.suggestReset ? "\n(detected change)" : ""}`,
}),
),
t.div(
@@ -317,6 +321,10 @@ export function pageCollections(route) {
pageData.filter = newFilter;
pageData.sort = newSort;
},
suggestReset: () => pageData.suggestReset,
onSuggestResetChange: (suggestReset) => {
pageData.suggestReset = !!suggestReset;
},
}),
t.footer(
{ className: "page-footer" },
+2 -1
View File
@@ -161,7 +161,6 @@ button {
&.danger {
color: var(--dangerColor);
}
&.accent,
&.secondary,
&.info,
&.success,
@@ -283,12 +282,14 @@ button {
}
}
&[data-rotate="true"],
&.rotate {
i {
animation: halfRotate 300ms;
}
}
&[data-loading="true"],
&.loading {
cursor: default;
&::after {
+48 -4
View File
@@ -31,6 +31,7 @@ window.app.components.recordsList = function(propsArg = {}) {
filter: "",
sort: "",
reset: undefined,
suggestReset: false,
// ---
rid: undefined,
id: undefined,
@@ -38,6 +39,7 @@ window.app.components.recordsList = function(propsArg = {}) {
className: "",
onchange: (newFilter, newSort) => {},
onselect: (record) => {},
onSuggestResetChange: (suggestReset) => {},
});
const watchers = app.utils.extendStore(props, propsArg);
@@ -84,6 +86,10 @@ window.app.components.recordsList = function(propsArg = {}) {
data.isLoading = true;
if (reset) {
props.suggestReset = false;
}
try {
// (note if changed update the related counter query too!)
const normalizedFilter = app.utils.normalizeSearchFilter(
@@ -240,6 +246,19 @@ window.app.components.recordsList = function(propsArg = {}) {
return field.hidden;
}
// note: for now always assuming single field sort
function getActiveSortKey() {
if (!props.sort) {
return "";
}
if (props.sort.startsWith("-") || props.sort.startsWith("+")) {
return props.sort.substring(1);
}
return props.sort;
}
let deleteRefreshTimeoutId;
const documentEvents = {
@@ -248,13 +267,25 @@ window.app.components.recordsList = function(propsArg = {}) {
return;
}
// optimistically merge with existing to minimize flickering
const found = data.records.find((r) => r.id == e.detail.id);
if (found) {
Object.assign(found, JSON.parse(JSON.stringify(e.detail)));
if (!found) {
return loadRecords(true);
}
loadRecords(true);
const sortKey = getActiveSortKey();
// loosely check if reload is needed
if (
// active server-side filter
props.filter?.length
// sorted value has changed
|| (sortKey && found[sortKey] != e.detail[sortKey])
) {
props.suggestReset = true;
}
// merge with existing
Object.assign(found, JSON.parse(JSON.stringify(e.detail)));
},
"record:delete": (e) => {
if (
@@ -331,6 +362,7 @@ window.app.components.recordsList = function(propsArg = {}) {
),
);
// persist columns prefereces
watchers.push(
watch(
() => JSON.stringify(data.columnsPreferences),
@@ -344,6 +376,18 @@ window.app.components.recordsList = function(propsArg = {}) {
},
),
);
// sync suggestReset
watchers.push(
watch(
() => props.suggestReset,
(newVal, oldVal) => {
if (typeof oldVal != "undefined") {
props.onSuggestResetChange?.(newVal);
}
},
),
);
},
onunmount: () => {
app.pb.cancelRequest(uniqueId);