feat: Make naming of library items discoverable (#10041)
Tests / test (push) Waiting to run Details

* updated library relevant strings

* fix: detect name changes

* clarify hashing function

---------

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
zsviczian 2025-09-30 20:38:10 +02:00 committed by GitHub
parent 7c41944856
commit fde796a7a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 24 additions and 6 deletions

View File

@ -29,6 +29,9 @@ export const hashElementsVersion = (elements: ElementsMapOrArray): number => {
// string hash function (using djb2). Not cryptographically secure, use only // string hash function (using djb2). Not cryptographically secure, use only
// for versioning and such. // for versioning and such.
// note: hashes individual code units (not code points),
// but for hashing purposes this is fine as it iterates through every code unit
// (as such, no need to encode to byte string first)
export const hashString = (s: string): number => { export const hashString = (s: string): number => {
let hash: number = 5381; let hash: number = 5381;
for (let i = 0; i < s.length; i++) { for (let i = 0; i < s.length; i++) {

View File

@ -518,7 +518,7 @@ const PublishLibrary = ({
</div> </div>
<div className="publish-library__buttons"> <div className="publish-library__buttons">
<DialogActionButton <DialogActionButton
label={t("buttons.cancel")} label={t("buttons.saveLibNames")}
onClick={onDialogClose} onClick={onDialogClose}
data-testid="cancel-clear-canvas-button" data-testid="cancel-clear-canvas-button"
/> />

View File

@ -62,6 +62,7 @@ type LibraryUpdate = {
deletedItems: Map<LibraryItem["id"], LibraryItem>; deletedItems: Map<LibraryItem["id"], LibraryItem>;
/** newly added items in the library */ /** newly added items in the library */
addedItems: Map<LibraryItem["id"], LibraryItem>; addedItems: Map<LibraryItem["id"], LibraryItem>;
updatedItems: Map<LibraryItem["id"], LibraryItem>;
}; };
// an object so that we can later add more properties to it without breaking, // an object so that we can later add more properties to it without breaking,
@ -170,6 +171,7 @@ const createLibraryUpdate = (
const update: LibraryUpdate = { const update: LibraryUpdate = {
deletedItems: new Map<LibraryItem["id"], LibraryItem>(), deletedItems: new Map<LibraryItem["id"], LibraryItem>(),
addedItems: new Map<LibraryItem["id"], LibraryItem>(), addedItems: new Map<LibraryItem["id"], LibraryItem>(),
updatedItems: new Map<LibraryItem["id"], LibraryItem>(),
}; };
for (const item of prevLibraryItems) { for (const item of prevLibraryItems) {
@ -181,8 +183,11 @@ const createLibraryUpdate = (
const prevItemsMap = arrayToMap(prevLibraryItems); const prevItemsMap = arrayToMap(prevLibraryItems);
for (const item of nextLibraryItems) { for (const item of nextLibraryItems) {
if (!prevItemsMap.has(item.id)) { const prevItem = prevItemsMap.get(item.id);
if (!prevItem) {
update.addedItems.set(item.id, item); update.addedItems.set(item.id, item);
} else if (getLibraryItemHash(prevItem) !== getLibraryItemHash(item)) {
update.updatedItems.set(item.id, item);
} }
} }
@ -586,12 +591,14 @@ class AdapterTransaction {
let lastSavedLibraryItemsHash = 0; let lastSavedLibraryItemsHash = 0;
let librarySaveCounter = 0; let librarySaveCounter = 0;
const getLibraryItemHash = (item: LibraryItem) => {
return `${item.id}:${item.name || ""}:${hashElementsVersion(item.elements)}`;
};
export const getLibraryItemsHash = (items: LibraryItems) => { export const getLibraryItemsHash = (items: LibraryItems) => {
return hashString( return hashString(
items items
.map((item) => { .map((item) => getLibraryItemHash(item))
return `${item.id}:${hashElementsVersion(item.elements)}`;
})
.sort() .sort()
.join(), .join(),
); );
@ -641,6 +648,13 @@ const persistLibraryUpdate = async (
} }
} }
// replace existing items with their updated versions
if (update.updatedItems) {
for (const [id, item] of update.updatedItems) {
nextLibraryItemsMap.set(id, item);
}
}
const nextLibraryItems = addedItems.concat( const nextLibraryItems = addedItems.concat(
Array.from(nextLibraryItemsMap.values()), Array.from(nextLibraryItemsMap.values()),
); );

View File

@ -230,10 +230,11 @@
"objectsSnapMode": "Snap to objects", "objectsSnapMode": "Snap to objects",
"exitZenMode": "Exit zen mode", "exitZenMode": "Exit zen mode",
"cancel": "Cancel", "cancel": "Cancel",
"saveLibNames": "Save name(s) and exit",
"clear": "Clear", "clear": "Clear",
"remove": "Remove", "remove": "Remove",
"embed": "Toggle embedding", "embed": "Toggle embedding",
"publishLibrary": "Publish selected", "publishLibrary": "Rename or publish",
"submit": "Submit", "submit": "Submit",
"confirm": "Confirm", "confirm": "Confirm",
"embeddableInteractionButton": "Click to interact" "embeddableInteractionButton": "Click to interact"