Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to select multiple for editing permissions #24

Closed
simonw opened this issue Sep 2, 2024 · 7 comments
Closed

Switch to select multiple for editing permissions #24

simonw opened this issue Sep 2, 2024 · 7 comments
Labels
enhancement New feature or request

Comments

@simonw
Copy link
Contributor

simonw commented Sep 2, 2024

Claude artifact showing what it could look like if I use this rather than the table of checkboxes:

https://claude.site/artifacts/3b83782b-74d3-4759-ac68-523fe2a905eb

CleanShot 2024-09-02 at 16 14 09@2x

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Group Permissions UI</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.css">
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            background-color: #f0f0f0;
        }
        .container {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        h1 {
            color: #333;
        }
        .group-row {
            display: flex;
            align-items: center;
            margin-bottom: 10px;
            padding: 10px;
            background-color: #f9f9f9;
            border-radius: 4px;
        }
        .group-name {
            width: 150px;
            font-weight: bold;
            color: #4a4a4a;
        }
        select[multiple] {
            min-width: 200px;
        }
        /* Choices.js custom styles */
        .choices__inner {
            min-height: 30px;
            padding: 4px 7.5px 4px 3.75px;
        }
        .choices__list--multiple .choices__item {
            font-size: 12px;
            padding: 2px 5px;
            margin-bottom: 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Group Permissions</h1>
        <div id="groups-container">
            <div class="group-row">
                <span class="group-name">staff (1)</span>
                <select multiple id="select-staff">
                    <option value="insert-row">insert-row</option>
                    <option value="delete-row">delete-row</option>
                    <option value="update-row">update-row</option>
                    <option value="alter-table" selected>alter-table</option>
                    <option value="drop-table">drop-table</option>
                </select>
            </div>
            <div class="group-row">
                <span class="group-name">devs (5)</span>
                <select multiple id="select-devs">
                    <option value="insert-row" selected>insert-row</option>
                    <option value="delete-row" selected>delete-row</option>
                    <option value="update-row" selected>update-row</option>
                    <option value="alter-table" selected>alter-table</option>
                    <option value="drop-table">drop-table</option>
                </select>
            </div>
            <div class="group-row">
                <span class="group-name">newgroup (0)</span>
                <select multiple id="select-newgroup">
                    <option value="insert-row">insert-row</option>
                    <option value="delete-row">delete-row</option>
                    <option value="update-row">update-row</option>
                    <option value="alter-table" selected>alter-table</option>
                    <option value="drop-table">drop-table</option>
                </select>
            </div>
            <div class="group-row">
                <span class="group-name">muppets (5)</span>
                <select multiple id="select-muppets">
                    <option value="insert-row">insert-row</option>
                    <option value="delete-row">delete-row</option>
                    <option value="update-row">update-row</option>
                    <option value="alter-table">alter-table</option>
                    <option value="drop-table">drop-table</option>
                </select>
            </div>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.2.0/choices.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const selects = document.querySelectorAll('select[multiple]');
            selects.forEach(select => {
                new Choices(select, {
                    removeItemButton: true,
                    classNames: {
                        containerOuter: 'choices custom-choices',
                    }
                });
            });
        });
    </script>
</body>
</html>

Conversation transcript: https://gist.github.com/simonw/7b87b24cd53daf8ea05170c3c8013e3c

I started with this screenshot:

image

Originally posted by @simonw in #23 (comment)

@simonw simonw added the enhancement New feature or request label Sep 2, 2024
@simonw simonw added this to the Feature complete milestone Sep 2, 2024
@simonw
Copy link
Contributor Author

simonw commented Sep 2, 2024

I think this UI will work better on narrow screens and will expand to handle more permissions.

@datasette datasette deleted a comment Sep 2, 2024
@simonw
Copy link
Contributor Author

simonw commented Sep 3, 2024

Here's an annoying problem:

CleanShot 2024-09-03 at 07 23 33@2x

Those look weird because the Datasette default CSS targets form button[type="button"] with a bunch of styles that don't work with Choices.

@simonw
Copy link
Contributor Author

simonw commented Sep 3, 2024

Similar visual glitches for the inputs themselves, thanks to default Datasette styles:

CleanShot 2024-09-03 at 07 25 35@2x

Disabling that all fixes it:

CleanShot 2024-09-03 at 07 26 29@2x

@simonw
Copy link
Contributor Author

simonw commented Sep 3, 2024

I think I need to introduce an opt-in mechanism to Datasette core classes, maybe a class of core - which can be used directly on the button or can be put on a wrapper element, such as a form.

@simonw
Copy link
Contributor Author

simonw commented Sep 9, 2024

I'm tempted to get Playwright tests working here, as seen in https://github.com/simonw/datasette-search-all/blob/main/tests/test_playwright.py

@simonw
Copy link
Contributor Author

simonw commented Sep 9, 2024

Another problem: https://github.com/simonw/datasette/blob/832f76ce26ffb2f3e27a006ff90254374bd90e61/datasette/utils/asgi.py#L138-L140

    async def post_vars(self):
        body = await self.post_body()
        return dict(parse_qsl(body.decode("utf-8"), keep_blank_values=True))

That means that a ` will only return the first selected item at the moment. need to work around that (and then fix it in Datasette core).

@simonw
Copy link
Contributor Author

simonw commented Sep 9, 2024

For the moment I'll work around that problem like so:

from datasette.utils import MultiParams

body = await self.post_body()
post_vars = MultiParams(parse_qs(qs=body, keep_blank_values=True))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant