diff --git a/apps/web/__e2e__/models/note-properties.model.ts b/apps/web/__e2e__/models/note-properties.model.ts
index 760b11944..1b06fc781 100644
--- a/apps/web/__e2e__/models/note-properties.model.ts
+++ b/apps/web/__e2e__/models/note-properties.model.ts
@@ -348,6 +348,7 @@ class SessionHistoryItemModel {
await fillPasswordDialog(this.page, password);
}
await this.previewNotice.waitFor();
+ await this.properties.close();
}
async isLocked() {
diff --git a/apps/web/src/components/attachment/index.tsx b/apps/web/src/components/attachment/index.tsx
index 40801afd8..3e99a29a9 100644
--- a/apps/web/src/components/attachment/index.tsx
+++ b/apps/web/src/components/attachment/index.tsx
@@ -170,11 +170,7 @@ export function Attachment({
) : processing?.working ? (
diff --git a/apps/web/src/components/note/index.tsx b/apps/web/src/components/note/index.tsx
index e1ff93d51..00ef54d70 100644
--- a/apps/web/src/components/note/index.tsx
+++ b/apps/web/src/components/note/index.tsx
@@ -147,10 +147,9 @@ function Note(props: NoteProps) {
body={note.headline as string}
onKeyPress={async (e) => {
if (e.key === "Delete") {
- const selectedItems = selectionStore
- .get()
- .selectedItems.filter((i) => i.type === item.type && i !== item);
- await Multiselect.moveNotesToTrash([item, ...selectedItems]);
+ // @ts-expect-error write tests for this
+ const selectedItems = selectionStore.get().selectedItems;
+ await Multiselect.moveNotesToTrash([item.id, ...selectedItems]);
}
}}
colors={{
diff --git a/apps/web/src/components/properties/index.tsx b/apps/web/src/components/properties/index.tsx
index b06257cb7..8bf101c47 100644
--- a/apps/web/src/components/properties/index.tsx
+++ b/apps/web/src/components/properties/index.tsx
@@ -265,8 +265,7 @@ function Notebooks({ noteId }: { noteId: string }) {
.selector.sorted(db.settings.getGroupOptions("notebooks"))
);
- if (result.status !== "fulfilled" || result.value.ids.length <= 0)
- return null;
+ if (result.status !== "fulfilled" || result.value.length <= 0) return null;
return (
@@ -274,7 +273,7 @@ function Notebooks({ noteId }: { noteId: string }) {
mode="fixed"
estimatedSize={50}
getItemKey={(index) => result.value.key(index)}
- items={result.value.ids}
+ items={result.value.placeholders}
renderItem={({ index }) => (
{({ item, data }) => (
@@ -292,8 +291,7 @@ function Reminders({ noteId }: { noteId: string }) {
.from({ id: noteId, type: "note" }, "reminder")
.selector.sorted(db.settings.getGroupOptions("reminders"))
);
- if (result.status !== "fulfilled" || result.value.ids.length <= 0)
- return null;
+ if (result.status !== "fulfilled" || result.value.length <= 0) return null;
return (
@@ -301,7 +299,7 @@ function Reminders({ noteId }: { noteId: string }) {
mode="fixed"
estimatedSize={54}
getItemKey={(index) => result.value.key(index)}
- items={result.value.ids}
+ items={result.value.placeholders}
renderItem={({ index }) => (
{({ item, data }) => (
@@ -319,15 +317,14 @@ function Attachments({ noteId }: { noteId: string }) {
.ofNote(noteId, "all")
.sorted({ sortBy: "dateCreated", sortDirection: "desc" })
);
- if (result.status !== "fulfilled" || result.value.ids.length <= 0)
- return null;
+ if (result.status !== "fulfilled" || result.value.length <= 0) return null;
return (
result.value.key(index)}
- items={result.value.ids}
+ items={result.value.placeholders}
header={<>>}
renderRow={({ index }) => (
@@ -354,8 +351,7 @@ function SessionHistory({
.get(noteId)
.sorted({ sortBy: "dateModified", sortDirection: "desc" })
);
- if (result.status !== "fulfilled" || result.value.ids.length <= 0)
- return null;
+ if (result.status !== "fulfilled" || result.value.length <= 0) return null;
return (
result.value.key(index)}
- items={result.value.ids}
+ items={result.value.placeholders}
renderItem={({ index }) => (
{({ item }) => (
diff --git a/apps/web/src/dialogs/add-tags-dialog.tsx b/apps/web/src/dialogs/add-tags-dialog.tsx
index f708bcfe8..90f0a89c3 100644
--- a/apps/web/src/dialogs/add-tags-dialog.tsx
+++ b/apps/web/src/dialogs/add-tags-dialog.tsx
@@ -112,7 +112,7 @@ function AddTagsDialog(props: AddTagsDialogProps) {
getItemKey={(index) => tags.key(index)}
mode="fixed"
estimatedSize={30}
- items={tags.ids}
+ items={tags.placeholders}
sx={{ mt: 2 }}
itemGap={5}
placeholders={{
diff --git a/apps/web/src/dialogs/attachments-dialog.tsx b/apps/web/src/dialogs/attachments-dialog.tsx
index b2ec74eaa..1e9fd7667 100644
--- a/apps/web/src/dialogs/attachments-dialog.tsx
+++ b/apps/web/src/dialogs/attachments-dialog.tsx
@@ -320,7 +320,7 @@ function AttachmentsDialog({ onClose }: AttachmentsDialogProps) {
mode="fixed"
estimatedSize={30}
getItemKey={(index) => attachments.key(index)}
- items={attachments.ids}
+ items={attachments.placeholders}
context={{
isSelected: (id: string) => selected.indexOf(id) > -1,
select: (id: string) => {
diff --git a/apps/web/src/utils/importer.ts b/apps/web/src/utils/importer.ts
index 249d6c71c..562cacc0c 100644
--- a/apps/web/src/utils/importer.ts
+++ b/apps/web/src/utils/importer.ts
@@ -70,7 +70,8 @@ async function processAttachment(
attachments: Record
) {
const name = path.basename(entry.name);
- if (!name || attachments[name] || db.attachments?.exists(name)) return;
+ if (!name || attachments[name] || (await db.attachments?.exists(name)))
+ return;
const { hashBuffer, writeEncryptedFile } = await import("../interfaces/fs");
@@ -92,7 +93,8 @@ async function processNote(entry: ZipEntry, attachments: Record) {
const note = await fileToJson(entry);
for (const attachment of note.attachments || []) {
const cipherData = attachments[attachment.hash];
- if (!cipherData || db.attachments?.exists(attachment.hash)) continue;
+ if (!cipherData || (await db.attachments?.exists(attachment.hash)))
+ continue;
await db.attachments?.add({
...cipherData,
diff --git a/packages/core/src/utils/virtualized-grouping.ts b/packages/core/src/utils/virtualized-grouping.ts
index d3c847263..8d25000d2 100644
--- a/packages/core/src/utils/virtualized-grouping.ts
+++ b/packages/core/src/utils/virtualized-grouping.ts
@@ -28,6 +28,7 @@ type Batch = {
export class VirtualizedGrouping {
private cache: Map> = new Map();
private pending: Map>> = new Map();
+ private _placeholders: boolean[] = [];
constructor(
readonly length: number,
@@ -43,6 +44,13 @@ export class VirtualizedGrouping {
readonly groups?: () => Promise<{ index: number; group: GroupHeader }[]>
) {}
+ get placeholders() {
+ if (this._placeholders.length !== this.length) {
+ this._placeholders = new Array(this.length).fill(true);
+ }
+ return this._placeholders;
+ }
+
key(index: number) {
return `${index}`;
}