Created share tag migration function
This commit is contained in:
@@ -873,6 +873,127 @@ export const subscribeToRealtime = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const runLegacyTagMigration = async () => {
|
||||||
|
const currentUserId = pb.authStore.model?.id;
|
||||||
|
if (!currentUserId) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userRec = await pb.collection('users').getOne(currentUserId, { requestKey: null });
|
||||||
|
const prefs = userRec.Taskgrid_pref || {};
|
||||||
|
|
||||||
|
if (prefs.migratedLegacyTagsV1) {
|
||||||
|
return; // Already migrated
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[MIGRATION] Starting legacy tag migration...");
|
||||||
|
|
||||||
|
// Fetch users and buckets
|
||||||
|
const [allUsers, allBuckets] = await Promise.all([
|
||||||
|
pb.collection('users').getFullList({
|
||||||
|
filter: 'verified = true',
|
||||||
|
fields: 'name,email',
|
||||||
|
requestKey: null
|
||||||
|
}),
|
||||||
|
pb.collection(BUCKETS_COLLECTION).getFullList({
|
||||||
|
fields: 'name',
|
||||||
|
requestKey: null
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
const validNames = new Set([
|
||||||
|
...allBuckets.map(b => b.name.toLowerCase()),
|
||||||
|
...allUsers.map(u => (u.name || u.email)?.toLowerCase()).filter(Boolean)
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Fetch all Tasks for this user
|
||||||
|
const tasks = await pb.collection(TASGRID_COLLECTION).getFullList({
|
||||||
|
filter: `user = "${currentUserId}"`,
|
||||||
|
requestKey: null
|
||||||
|
});
|
||||||
|
|
||||||
|
let tasksUpdated = 0;
|
||||||
|
for (const t of tasks) {
|
||||||
|
if (!t.tags || t.tags.length === 0) continue;
|
||||||
|
let changed = false;
|
||||||
|
const newTags = t.tags.map((tag: string) => {
|
||||||
|
if (!tag.startsWith("@") && validNames.has(tag.toLowerCase())) {
|
||||||
|
changed = true;
|
||||||
|
return `@${tag}`;
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
await pb.collection(TASGRID_COLLECTION).update(t.id, { tags: newTags }, { requestKey: null });
|
||||||
|
tasksUpdated++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch all Notes for this user
|
||||||
|
const notes = await pb.collection(NOTES_COLLECTION).getFullList({
|
||||||
|
filter: `user = "${currentUserId}"`,
|
||||||
|
requestKey: null
|
||||||
|
});
|
||||||
|
|
||||||
|
let notesUpdated = 0;
|
||||||
|
for (const n of notes) {
|
||||||
|
if (!n.tags || n.tags.length === 0) continue;
|
||||||
|
let changed = false;
|
||||||
|
const newTags = n.tags.map((tag: string) => {
|
||||||
|
if (!tag.startsWith("@") && validNames.has(tag.toLowerCase())) {
|
||||||
|
changed = true;
|
||||||
|
return `@${tag}`;
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
await pb.collection(NOTES_COLLECTION).update(n.id, { tags: newTags }, { requestKey: null });
|
||||||
|
notesUpdated++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.migratedLegacyTagsV1 = true;
|
||||||
|
await pb.collection('users').update(currentUserId, { Taskgrid_pref: prefs }, { requestKey: null });
|
||||||
|
|
||||||
|
if (pb.authStore.model) {
|
||||||
|
pb.authStore.model.Taskgrid_pref = prefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[MIGRATION] Completed. Updated ${tasksUpdated} tasks and ${notesUpdated} notes.`);
|
||||||
|
|
||||||
|
// Update local state directly so it reflects immediately
|
||||||
|
setStore("tasks", (tasks) => tasks.map(t => {
|
||||||
|
let localChanged = false;
|
||||||
|
const nt = t.tags?.map(tag => {
|
||||||
|
if (!tag.startsWith("@") && validNames.has(tag.toLowerCase())) {
|
||||||
|
localChanged = true;
|
||||||
|
return `@${tag}`;
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
});
|
||||||
|
if (localChanged) return { ...t, tags: nt };
|
||||||
|
return t;
|
||||||
|
}));
|
||||||
|
|
||||||
|
setStore("notes", (items) => items.map(n => {
|
||||||
|
let localChanged = false;
|
||||||
|
const nt = n.tags?.map(tag => {
|
||||||
|
if (!tag.startsWith("@") && validNames.has(tag.toLowerCase())) {
|
||||||
|
localChanged = true;
|
||||||
|
return `@${tag}`;
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
});
|
||||||
|
if (localChanged) return { ...n, tags: nt };
|
||||||
|
return n;
|
||||||
|
}));
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error("[MIGRATION] Failed:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const initStore = async () => {
|
export const initStore = async () => {
|
||||||
if (!pb.authStore.isValid || store.isInitializing) return;
|
if (!pb.authStore.isValid || store.isInitializing) return;
|
||||||
setStore("isInitializing", true);
|
setStore("isInitializing", true);
|
||||||
@@ -1205,6 +1326,9 @@ export const initStore = async () => {
|
|||||||
// Fire off background sync
|
// Fire off background sync
|
||||||
await backgroundSync();
|
await backgroundSync();
|
||||||
|
|
||||||
|
// Run one-time migration for legacy tags
|
||||||
|
await runLegacyTagMigration();
|
||||||
|
|
||||||
// Separate Templates load (less critical)
|
// Separate Templates load (less critical)
|
||||||
try {
|
try {
|
||||||
const templates = await pb.collection(TASGRID_COLLECTION).getFullList({
|
const templates = await pb.collection(TASGRID_COLLECTION).getFullList({
|
||||||
|
|||||||
Reference in New Issue
Block a user