aws / graph-explorer

React-based web application that enables users to visualize both property graph and RDF data and explore connections between data without having to write graph queries.
https://github.com/aws/graph-explorer
Apache License 2.0
332 stars 49 forks source link

[Feature Request] The user preference is not persistent #173

Open StrongPa55word opened 1 year ago

StrongPa55word commented 1 year ago

Community Note

Graph Explorer Version (and Graph Database and Version used if applicable)

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm frustrated when [...]

Describe the solution you'd like It would be ideal to save defaults for Display Attributes( Color/Styling/Property Labels ). Currently the sessions are saved on client side.

Additional context Add any other context or screenshots about the feature request here. Describe any alternatives you've considered.

kmcginnes commented 6 months ago
kmcginnes commented 1 month ago

@StrongPa55word To clarify, do you mean that styles should be persisted to the server and shared amongst all users for that server?

Today, any customization you make to the styles are persisted to the browser's local storage. This means those customizations are isolated to that one browser.

henrieglesorotos commented 1 month ago

I would also love configurations being persisted server side. Would be a big help for us.

kmcginnes commented 1 month ago

Gotcha. That is something that is not out of the question. But as of right now we have zero server side data persistence. If that changes, saving the configurations server side would become an option.

henrieglesorotos commented 1 month ago

Gotcha. That is something that is not out of the question. But as of right now we have zero server side data persistence. If that changes, saving the configurations server side would become an option.

We looked at using a bookmarklet to run the formatting on load in the browser, but ran into problems.

tomjennings-beamery commented 1 month ago

We looked at using a bookmarklet to run the formatting on load in the browser, but ran into problems.

yeh just to add some colour here, we extracted what we thought were the relevant tables from IndexedDB, then attempted to overwrite with a bookmarklet. We're overwriting the DB successfully, but it's not persisting a refresh unfortunately.

(function () {
    let dbName = 'ge';
    let dbVersion;
    let canonicalData = {
        "graph_explorer": [
            "Default Connection",
            {},
            {},
            {
                "activeToggles": {},
                "activeSidebarItem": "expand",
                "detailsAutoOpenOnSelection": true,
                "tableView": { "height": 300 }
            },
            {
                "vertices": [
                    {
                        "type": "http://www.w3.org/2004/02/skos/core#Concept",
                        "displayLabel": "label"
                    },
                    {
                        "type": "https://schema.org/blah",
                        "displayLabel": "Label",
                        "color": "#ff0000",
                        "shape": "barrel",
                        "backgroundOpacity": 1,
                        "displayNameAttribute": "https://schema.org/name"
                    },
                    {
                        "type": "http://www.w3.org/2004/02/skos/core#ConceptScheme",
                        "displayNameAttribute": "http://www.w3.org/2004/02/skos/core#prefLabel",
                        "shape": "diamond",
                        "color": "#ff0000"
                    }
                ],
                "edges": [
                    {
                        "type": "http://www.w3.org/2004/02/skos/core#inScheme",
                        "displayLabel": "is a type of"
                    },
                    {
                        "type": "http://www.w3.org/2004/02/skos/core#relatedMatch",
                        "displayLabel": "related to"
                    }
                ]
            }
        ],
        "local-forage-detect-blob-support": []
    };

    let initialRequest = indexedDB.open(dbName);

    initialRequest.onerror = function (event) {
        console.error('Error opening database:', event);
    };

    initialRequest.onsuccess = function (event) {
        let db = event.target.result;
        dbVersion = db.version;
        db.close(); 
        let newVersion = dbVersion + 1;
        let openRequest = indexedDB.open(dbName, newVersion);

        openRequest.onupgradeneeded = function (event) {
            let db = event.target.result;

            Object.keys(canonicalData).forEach(function (storeName) {
                if (db.objectStoreNames.contains(storeName)) {
                    db.deleteObjectStore(storeName);
                    console.log(`Deleted object store: ${storeName}`);
                }

                db.createObjectStore(storeName);
                console.log(`Created object store: ${storeName}`);
            });
        };

        openRequest.onsuccess = function (event) {
            let db = event.target.result;

            let transaction = db.transaction(Object.keys(canonicalData), 'readwrite');

            transaction.oncomplete = function () {
                console.log('Database has been updated with canonical data.');
            };

            transaction.onerror = function (event) {
                console.error('Transaction error:', event);
            };

            Object.keys(canonicalData).forEach(function (storeName) {
                let store = transaction.objectStore(storeName);
                let data = canonicalData[storeName];

                if (Array.isArray(data)) {
                    data.forEach(function (item, index) {
                        let request = store.add(item, index); // Using index as the key
                        request.onerror = function (event) {
                            console.error(`Error adding data to ${storeName}:`, event);
                        };
                    });
                } else {
                    let request = store.add(data, 0);
                    request.onerror = function (event) {
                        console.error(`Error adding data to ${storeName}:`, event);
                    };
                }
            });
        };

        openRequest.onerror = function (event) {
            console.error('Error opening database with new version:', event);
        };
    };
})();

I assume either we corrupted the database somehow, or we're missing something!

kmcginnes commented 1 month ago

Hmm, interesting approach. In theory it should work. But perhaps the changes the bookmarklet is making are overwritten before the refresh can happen.

Another approach could be to use the save/load configuration feature. You can save the user's configuration data to a JSON file, then use a utility of some kind to modify the JSON data by inserting your common styles, then load that modified configuration data. It's not as simple as it should be, but it might provide a workable option until something better comes along.