Coder Social home page Coder Social logo

piccolo-orm / piccolo_admin Goto Github PK

View Code? Open in Web Editor NEW
283.0 7.0 34.0 9.11 MB

A powerful web admin for your database.

Home Page: https://piccolo-orm.com/ecosystem/

License: MIT License

Python 46.30% JavaScript 0.22% HTML 0.11% Vue 44.07% TypeScript 7.71% Shell 0.25% Less 1.34%
piccolo asgi python3 asyncio admin dashboard postgresql sqlite vuejs database

piccolo_admin's Introduction

Logo

Piccolo Admin

Documentation Status

Piccolo Admin is a powerful admin interface / content management system for Python, built on top of Piccolo.

Screenshot

It was created at a design agency to serve the needs of customers who demand a high quality, beautiful admin interface for their websites. It's a modern alternative to tools like Wordpress and Django Admin.

It's built using the latest technologies, with Vue.js on the front end, and a powerful REST backend.

Some of it's standout features:

  • Powerful data filtering
  • Builtin security
  • Media support, both locally and in S3 compatible services
  • Dark mode support
  • CSV exports
  • Easily create custom forms
  • Works on mobile and desktop
  • Use standalone, or integrate it easily with ASGI apps like FastAPI, and Starlette
  • Multilingual out of box
  • Bulk actions, like updating and deleting data
  • Flexible UI - only show the columns you want your users to see

Try it

Try it online (username: piccolo, password: piccolo123).

Local Demo

To run a demo locally, using Python 3.8 or above:

pip install piccolo_admin
admin_demo

And then just launch localhost:8000 in your browser.

To see what happens behind the scenes, see piccolo_admin/example.py.

In a few lines of code we are able to:

  • Define our models
  • Setup a database
  • Create a REST API
  • Setup a web server and admin interface

ASGI

Since the admin is an ASGI app, you can either run it standalone like in the demo, or integrate it with a larger ASGI app such as FastAPI and Starlette.

For example, using Starlette routes:

import uvicorn
from movies.endpoints import HomeEndpoint
from movies.tables import Director, Movie
from starlette.routing import Mount, Route, Router

from piccolo_admin.endpoints import create_admin

# The `allowed_hosts` argument is required when running under HTTPS. It's
# used for additional CSRF defence.
admin = create_admin([Director, Movie], allowed_hosts=["my_site.com"])


router = Router(
    [
        Route(path="/", endpoint=HomeEndpoint),
        Mount(path="/admin/", app=admin),
    ]
)


if __name__ == "__main__":
    uvicorn.run(router)

Full docs

Full documentation is available on Read the docs.

piccolo_admin's People

Contributors

abhijithganesh avatar aminalaee avatar dantownsend avatar dependabot[bot] avatar ethagnawl avatar hblunck avatar jrycw avatar lemeteore avatar lgtm-com[bot] avatar mnixry avatar nazmiasri95 avatar northpowered avatar olliglorioso avatar omerucel avatar ruslan-rv-ua avatar sinisaos avatar web-maker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

piccolo_admin's Issues

Add an option to auto apply filters

It would be nice to have an 'auto apply' option in the filter sidebar.

When the option is disabled, the filters are applied by manually pressing the 'apply' button:

auto_submit_disabled

When the option is enabled, the 'apply' button is hidden, and when any of the values change in the sidebar, an API call will be made to refresh the data:

auto_submit_enabled

CSRF fixes when served under HTTPS

Brought to attention in this issue:

piccolo-orm/piccolo#8

create_admin doesn't expose arguments for CSRFMiddleware - most importantly allowed_hosts, which is an extra layer of protection when served under HTTPS.

It means that when the admin is served directly under HTTPS, rather than behind a proxy, the CSRF middleware will always block the request.

Use `__visible_fields`

We added the __visible_fields GET parameter to the API, but we're not currently using it for Piccolo Admin's list page.

Tweaks to release script

If trying to release via GitHub there's currently a problem because the node dependencies aren't installed.

Docker image

It would be really cool if we had a Docker image for Piccolo Admin.

It would have environment variables such as: PG_HOST, PG_PASSWORD etc to tell it how to connect to Postgres.

To determine which tables to connect to, it would either use a config file mounted in a volume, or would accept another environment variable called PICCOLO_TABLES. For example PICCOLO_TABLES=article,post.

Since Piccolo now has powerful schema reflection abilities, we can generate the Piccolo Table classes automatically.

It would open up Piccolo admin to a much wider user base (including non-Python users).

Synchronise the filters with the GET parameters

There's a little known feature in Piccolo admin where you can filter the row listing page using GET params. For example:

/#/movie?won_oscar=true

However, these values aren't synchronised with the filter sidebar:

  • When the page loads, the filter sidebar doesn't display the values in the GET params
  • When the filter sidebar values change, the GET params don't update accordingly

Having this work properly would be a nice feature. It will allow a user to do the following:

  • Load the listing page, and apply some filters
  • Click on one of the results, and edit it
  • Press the back button, and the same filters will still be applied

Filter between

When filtering a number column, you can specify whether you want less than, equal, or greater than.

It would be great to also have a between option. When this is selected, two input fields would be rendered.

Screenshot 2021-10-27 at 21 39 02

Using bigint is broken due to json max size

Using bigint on large bigints like discord snowflakes (like 818294562677588009) causes it to be rounded/corrupted during transfer due to json max size limits.

For bigint, use string and manually parse the integer maybe?

Add custom widget for Interval fields

Any Interval fields are shown as text boxes, where you input a number of seconds. It works fine, but could be more user friendly.

The schema for a table with an Interval column looks like this (accessible via /api/tables/my_table/schema).

{
    "title": "MyTableIn",
    "type": "object",
    "properties": {
        "interval": {
            "title": "Interval",
            "extra": {},
            "nullable": false,
            "type": "number",
            "format": "time-delta"
        }
    }
}

We can tell if it's an Interval from the format field in the schema, which is "time-delta".

Nullable foreign keys

There's a bug when trying to add a row with a foreign key. If the foreign key is nullable, and you try and submit an empty value, validation will fail, as Pydantic sees it as an empty string, and not None. The error returned will then be something like a string isn't a valid type.

The front end needs modifying to return null in these situations.

Roadmap

  • Be able to bulk delete items in the admin
  • Be able to bulk modify items in the admin
  • Improve pagination when dealing with lots of data in a table.
  • CSV export
  • Add a custom widget for Interval fields - currently just accepts a number of seconds.
  • Use FastAPI for the API
  • User management - creating users and changing passwords via the UI
  • Be able to change the page size (i.e. number of results per page) dynamically in the UI
  • Be able to specify a site name in create_admin, so the UI shows MySite Admin in the nav bar, rather than the default Piccolo Admin

LocalProtocolError: Too much data for declared Content-Length

First of all: Thanks for creating piccolo adn piccolo-admin - it looks really good!!

When using piccolo_admin with Fastapi running in uvicorn, I'm getting this error whenever I delete an object in piccolo-admin.

Traceback (most recent call last):
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 373, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/fastapi/applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/routing.py", line 408, in handle
    await self.app(scope, receive, send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/middleware/base.py", line 56, in __call__
    await response(scope, receive, send)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/responses.py", line 227, in __call__
    await wrap(partial(self.listen_for_disconnect, receive))
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/anyio/_backends/_asyncio.py", line 567, in __aexit__
    raise exceptions[0]
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/responses.py", line 223, in wrap
    await func()
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/responses.py", line 215, in stream_response
    await send({"type": "http.response.body", "body": chunk, "more_body": True})
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 68, in sender
    await send(message)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 68, in sender
    await send(message)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 156, in _send
    await send(message)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 469, in send
    output = self.conn.send(event)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/h11/_connection.py", line 468, in send
    data_list = self.send_with_data_passthrough(event)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/h11/_connection.py", line 501, in send_with_data_passthrough
    writer(event, data_list.append)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/h11/_writers.py", line 58, in __call__
    self.send_data(event.data, write)
  File "/projects/customer-api/.venv/lib/python3.9/site-packages/h11/_writers.py", line 78, in send_data
    raise LocalProtocolError("Too much data for declared Content-Length")
h11._util.LocalProtocolError: Too much data for declared Content-Length

Relevant packages:

piccolo-admin==0.18.1
  - aiofiles [required: >=0.5.0, installed: 0.7.0]
  - fastapi [required: >=0.62.0, installed: 0.70.0]
    - pydantic [required: >=1.6.2,<2.0.0,!=1.8.1,!=1.8,!=1.7.3,!=1.7.2,!=1.7.1,!=1.7, installed: 1.8.2]
      - typing-extensions [required: >=3.7.4.3, installed: 3.10.0.2]
    - starlette [required: ==0.16.0, installed: 0.16.0]
      - anyio [required: >=3.0.0,<4, installed: 3.3.4]
        - idna [required: >=2.8, installed: 3.3]
        - sniffio [required: >=1.1, installed: 1.2.0]
  - Hypercorn [required: Any, installed: 0.12.0]
    - h11 [required: Any, installed: 0.12.0]

Prettier sidebar items

If the table name is really long, it wraps like this:

Screenshot 2021-10-27 at 13 22 01

It would look a bit nicer if it was like this instead:

139064455-1766ca12-2bf2-4cc4-aab2-ccb3f161dc9a

This can be done using flexbox in CSS.

Better UI for JSON fields

JSON fields are just treated as strings in the UI.

It would be nice if the UI had an option to show a nicely rendered view of the JSON.

Not working

The admin panel just gives me a blank page when I try visiting it. No errors in console

`TableConfig` name overrides

If there's a column or a table with a terrible name, it would be nice to override it in the admin.

app = create_admin(
    TableConfig(
        TableWithRegrettableName,
        name_override="A nice table name",
        column_name_overrides={TableWithRegrettableName.regrettable_column_name: 'A nice column name'}
    )
)

Automate running of Cypress tests

Now we have some basic Cypress tests, it is worth investigating how we can run these as part of GitHub actions.

Cypress tests can be notoriously slow, so we might not want to run them on every commit - we will have to see what the performance is like.

Hybrid foreign key selector

For foreign key columns, we used to use a HTML select for picking values.

We replaced it with a search box. This was necessary because the page would crash when using a select if the related table had a lot of rows.

Screenshot 2021-10-27 at 13 27 55

In certain situations the select box is better though. For example, if the related table only has a handful of rows, it's easier to just select the one you want.

The downside of a search box is you need some prior knowledge of what you're looking for.

It might be possible to create a hybrid. When you click on the search box, and haven't typed anything, it automatically shows the first 10 possible results.

`TableConfig` media handlers

This is a big task, but unlocks a lot of great functionality in the admin.

Piccolo doesn't have a particular column type for storing media (images, video etc). It's possible to store them in binary columns, but this is generally frowned upon as it quickly leads to database bloat (and database storage is typically much more expensive than object storage).

The usual approach for storing media is to put the file in object storage (like S3), or in a local directory, and store a reference to it in the database (for example a URL or path).

Initially we can just store the media files in a local directory, but supporting the S3 protocol would be great in the future.

The steps required to implement this:

MediaHandler class

# This is just an abstract base class for all other media handlers:
class MediaHandler:
    pass

@dataclass
class LocalMediaHandler(MediaHandler):
    root_path: str

    def store_file(self, file):
        ...

    def retrieve_file(self, path: str):
        ...

TableConfig changes

media_handler = LocalMediaHandler(root_path='/var/www/files/')

app = create_admin(
    TableConfig(
        Movie,
        media_handler=media_handler,
        media_columns=[Movie.poster]
    )
)

PiccoloCRUD changes

There will be a new endpoint, something like:

/tables/director/1/media?column=poster

Which can be used to retrieve the actual media file.

UI improvements

The UI will know if a column is used for media storage by inspecting the JSON schema:

/api/tables/director/schema

PiccoloCRUD would've added an extra field to it called 'media_columns', using create_pydantic_model's schema_extra_kwargs feature.

The UI would then render a file upload box for that field. In the future we could support simple editing functionality like cropping images (there are several JS libraries for this), but that's down the road.

Add scripts folder

Following this:

  • Move all the scripts to the scripts folder
  • Update github workflows to use the scripts

Abstraction for generic admin panel use

Firstly, thanks so much for your amazing work on this project.

I'm looking to build a generic library for admin interface components that tie into CRUD operations within ASGI apps, since one doesn't really exist within the ASGI ecosystem. Since the piccolo_admin Vue app is predominantly built of well-separated components, and relies on a well-defined API layer, it could form a good foundation for this project; alternative CRUD backends could be created that conform to a similar API spec, and therefore make use of the frontend components you've built.

I was considering forking the project to achieve this, but I was wondering if you'd be willing to collaborate with me in abstracting some of the components of the admin panel into a generic library of admin interface components? The piccolo admin panel would have to be somewhat restructured to make use of the components in the library, but the components themselves would see more broad use as they could be included as a more integrated part of other web apps.

Certain abstractions, like allowing fetchTableNames to be either served by an API endpoint or hard-coded, would allow the end developer to decouple the Vue app from the specifics of the API structure as defined here, and therefore depend only on the CRUD routes.

One advantage of this approach is that both the piccolo project and any parallel projects using the same admin panel library would mutually benefit from updates to the interface components. More eyeballs on the code might help push this forward to become the prevailing open source admin panel for API-driven web apps. Indeed, existing ASGI apps could use this library to easily add a custom admin panel without changing their underlying ORM.

It would be interesting to hear your thoughts πŸ˜„

Post Edit Hooks

Sorry for all the issues, but here’s another feature that would be nice. Make it so you can register a callback function for whenever an edit, deletion or addition to a table happens

Improve foreign key selector when dealing with lots of rows

The foreign key selectors are select HTML elements. These are used in the sidebar for filtering, and for changing foreign key values in detail views.

It works fine when the number of values is relatively small. If there are thousands of values, it could become less useful.

Screenshot 2021-02-03 at 20 12 22

A search box might be better in these situations.

PiccoloCRUD has an ids endpoint - /api/tables/<tablename>/ids which returns a mapping of row ID to a readable value. For example:

{
    "1": "Peter Jackson",
    "2": "George Lucas",
    "3": "J.J. Abrams",
    "4": "Gareth Edwards",
    "5": "Irvin Kershner",
    "6": "Richard Marquand",
    "7": "Rian Johnson",
    "8": "Ron Howard"
}

Try it out here.

The endpoint could be modified to return data in this format:

{
    "total_count":  8,
    "response_count": 8,
    "rows": {
        "1": "Peter Jackson",
        "2": "George Lucas",
        "3": "J.J. Abrams",
        "4": "Gareth Edwards",
        "5": "Irvin Kershner",
        "6": "Richard Marquand",
        "7": "Rian Johnson",
        "8": "Ron Howard"
    }
}

If there were lots of values, it would return something like this:

{
    "total_count":  5000,
    "response_count": 100,
    "rows": {
        "1": "Peter Jackson",
        "2": "George Lucas",
        "3": "J.J. Abrams",
        "4": "Gareth Edwards",
        "5": "Irvin Kershner",
        "6": "Richard Marquand",
        "7": "Rian Johnson",
        ...
        "100": "Quentin Tarantino",
    }
}

By default, a maximum of 100 results will be returned at once. If response_count < total_count we should show the search UI rather than just a dropdown.

The ids endpoint should accept a search parameter, which can be used to filter what's returned. For example:

// /api/tables/director/ids?search=george
{
    "total_count":  2,
    "response_count": 2,
    "rows": {
        "1": "George Lucas",
        "50": "George Armitage",
    }
}

The search UI could look something like this:

sZFsT

Implement custom forms

One of the main strengths of Piccolo admin is it's ability to turn a Pydantic model into a form in the UI. Currently, these Pydantic models are generated from Piccolo Table subclasses.

It would be amazing if a custom Pydantic model can be passed to create_admin, and it's rendered as a form in the UI. For example:

@dataclasses.dataclass
class FormConfig:
    name: str
    pydantic_model: Type[BaseModel]
    endpoint: Callable


def send_email_endpoint(request, data):
    send_email(data.email, data.title, data.content)
    return 'Success'


class SendEmailModel(BaseModel):
    email: str
    title: str
    content: str


app = create_admin(
    tables=[Director, Movie],
    forms=[
        FormConfig(
            name="Send email",
            pydantic_model=SendEmailModel,
            endpoint=send_email_endpoint
        )
    ]
)

A new section would then be rendered in the sidebar.

piccolo_admin_forms_sidebar

Clicking on one of the forms in the sidebar would open a page containing the form.

When the form is submitted, it would call the specified endpoint.

Adding this to Piccolo admin would massively improve it's utility - some business apps could be built with it, without having to write a single line of front end code.

Session auth expiry

The session auth currently expires automatically after 1 hour. This should be extended automatically if the user is still using the app. This is a small issue with piccolo_api - the middleware is unable to extend the cookie expiry at present, so needs refactoring so it doesn't use Starlette's Auth middleware.

Loading indicators

When the network is very slow and / or a lot of data is being pulled from the API, you can see the UI load.

Investigate whether having load spinners improves or degrades the user experience.

Form fields pre-population

Custom forms are a great feature and look like a quick way to add some calculations or other custom logic to be run from within the admin.

I've been wondering if there would be a possibility to pre-populate form fields so that the user would not only be able to type into blank fields or use hardcoded selects but rather select from a dropdown that was dyjamically generated i.e. from contents of some table?

I imagine that same way as form currently has handler function to be run on submit, there could be a init function that would set up the form fields ie with initial text or generate options for select field. You could run the piccolo ORM query in that init function and then do some logic that would modify the fields defined earlier as Pydantic model

Find a different date time picker

The date time picker is a pain on mobile - it works OK on Android, but doesn't really work on iOS.

An alternative needs to be found which can work for dates and times, and integrates well with Vue JS.

See the discussion here: #34

Add JS format settings

We currently don't have the settings in the docs for the JS auto formatting.

#113 (comment)

In my .vscode/settings.json, I currently have:

{
    // TS files
    "prettier.tabWidth": 4,
    "prettier.singleQuote": false,
    "prettier.semi": false,
    "prettier.trailingComma": "none",

    // Vetur
    "vetur.format.options.tabSize": 4,
    "vetur.format.options.useTabs": false,
    "vetur.format.enable": true,
    "vetur.format.defaultFormatter.js": "prettier",
    "vetur.format.defaultFormatterOptions": {
        "prettier": {
            "singleQuote": false,
            "semi": false,
            "tabSize": 4,
            "trailingComma": "none"
        },
        "prettyhtml": {
            "printWidth": 100,
            "singleQuote": false,
            "wrapAttributes": true,
            "sortAttributes": true
        }
    },
}

There is some duplication, as Vetur only formats Vue files, and not standalone TS files.

The purpose of this issue is to try and create a definitive formatting config.

Add proper docs

At the moment, all of the docs are in the README.

I think it would benefit from proper docs on readthedocs.org, as the project grows in scope.

For example, the README currently doesn't explain how to create admin users on the command line, or how to set a custom title for the admin.

Implement TableConfig class

Currently, create_admin accepts a list of Table subclasses. This can be modified to accept either Table subclasses, or instances of a new class called TableConfig.

TableConfig will be a dataclass which accepts a table argument, as well as a bunch of configuration options. For example:

@dataclasses.dataclass
class TableConfig:
    """
    :param list_columns:
        Used to specify which columns are shown on the list page. If None,
        all are shown.
    :param list_filters:
        Used to specify which filters are shown on the list page. If None,
        all are shown.

    """
    table: Type[Table]
    list_columns: Optional[List[Union[str, Column]] = None
    list_filters: Optional[List[Union[str, Column]] = None
    # Plus some additional options, which haven't been finalised.
    ...

app = create_admin(
    tables=[
        SomeTable,
        TableConfig(
            table=MyTable,
            list_columns=[MyTable.name],
            list_filters=[MyTable.name]
        )
    ]
)

It will allow more fine grained control of the how the admin looks.

Find a replacement for window.opener.postMessage

Chrome recently changed how it treats links like <a href="/some-link" target="_blank">Click me</a>.

It now sets window.opener as undefined on the window / tab which gets opened.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#browser_compatibility
window.opener was used by Piccolo Admin to communicate between tabs, so when clicking on the add or edit links above a foreign key selector, it would open the edit/add page in a new tab, and when saved would tell the parent tab to refresh its list of foreign key options.

Screenshot 2021-03-11 at 22 46 25

It's currently used here, and here.

Possible solutions:

  • Somehow use a different target type for links
  • Open the page in an iframe instead, in a popup modal

Use FastAPIWrapper for the API

Having Swagger documentation for the API would be useful during development, and potentially for some end users.

FastAPIWrapper is built on top of PiccoloCRUD, so the API should be the same, but this needs to be verified.

Cypress tests

When new features are added to Piccolo, a lot of manual testing is involved with Piccolo Admin.

It would be much nicer to have a tool like Cypress, and a simple suite of automated tests.

Initially, having the following would be great:

  • Testing that the login page works
  • Testing that the list page works, with some basic filtering
  • Testing that the detail page works (ideally with adding / editing a row)

Make tables and forms collapsible in sidebar

When you look at the UI for the sidebar, it looks like clicking on Tables or Forms would hide what's underneath.

Screenshot 2021-10-27 at 13 17 16

It would be quite a useful feature, because some apps end up with dozens of tables, which pushes forms off the bottom of the page. If you could click on Tables to collapse it, then it would be easier than scrolling to the bottom.

Null byte string error!

I got null byte string error when tried to run piccolo_admin! The problem was in init file! There was string with null bytes! Also version.py was empty!
I downloaded it from pypi!

Form improvements

I've been using form a lot, and there are a couple of things which could be improved.

FormConfig should accept coroutines as well as standard functions.

When there's an error, the banner shows up in green. I think we have the ability to show it in red.

Implement proxying in Vue CLI

In the current contributing docs, it mentions having to setup a proxy server such as Nginx, so the front end and backend can be consumed from the same domain.

There is a feature built into Vue CLI, which will automatically proxy certain paths.

https://cli.vuejs.org/config/#devserver-proxy

This is easier than having to setup a separate proxy server.

If we implement this change, it might make it easier for people to get the Piccolo admin running locally.

Nullable timestamp fields

In the UI, if there's a timestamp field and you try to save it with an empty value, you'll get a validation error.

It's because it's being sent to the API as an empty string, rather than null.

We need to modify it, so null is being sent back instead.

Upgrade to Vue 3

Vue 2 should still be fine for some time, but Vue 3 is definitely a step up. A first step is working out how much work is involved.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.