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

Input field disappearing when clicking 'Add'. #386

Open
AmazingAkai opened this issue Apr 25, 2024 · 13 comments
Open

Input field disappearing when clicking 'Add'. #386

AmazingAkai opened this issue Apr 25, 2024 · 13 comments

Comments

@AmazingAkai
Copy link

AmazingAkai commented Apr 25, 2024

class NewStaff(BaseModel):
    name: Annotated[str, Field(max_length=255, pattern=r"^[a-zA-Z\s]+$")]
    email: EmailStr
    superuser: bool
    permissions: list[Permission]
    
    
async def new_staff_endpoint(request: Request, data: NewStaff) -> str:
    ... # user creation code...


NEW_STAFF_FORM = FormConfig(
    name="New Staff",
    description="Create a new staff member.",
    pydantic_model=NewStaff,
    endpoint=new_staff_endpoint,
)

Permission is just an enum

class Permission(Enum):
    UPLOADS = "uploads"
    NOTICES = "notices"
    GALLERY = "gallery"
    ADMISSIONS = "admissions"
Screencast_20240425_213515.webm
@sinisaos
Copy link
Member

@AmazingAkai This can be fixed by including optional parameter on this line

isMediaColumn() {
return this.schema.extra.media_columns.includes(this.fieldName)
}

like this

isMediaColumn() {
    return this.schema?.extra.media_columns.includes(this.fieldName)
}

Result is:

add_button.webm

But then we have another problem because Piccolo Admin doesn't understand "$ref": "#/$defs/Permission" (json reference) to Permission enum and enum attributes are not displayed as HTML select. It seems that custom forms can currently only work with str, int, bool etc. but not with json reference to enums or another Pydantic models.

@dantownsend
Copy link
Member

@sinisaos I think adding this for now makes sense:

isMediaColumn() {
    return this.schema?.extra.media_columns.includes(this.fieldName)
}

At some point we need to refactor things a bit so InputField doesn't try getting the schema from the store, but I think this solution is good for now.

@sinisaos
Copy link
Member

@dantownsend I agree with you and it will solve a smaller part of the problem. The larger part is that Piccolo Admin can't understand the json reference as I wrote in the previous comment and how to solve it so that custom forms work with enums and another Pydantic models as reference.

@dantownsend
Copy link
Member

Yeah, OpenAPI schemas are surprisingly complex - especially the references etc.

@sinisaos
Copy link
Member

@AmazingAkai I was thinking about how we could use a Python enum in array widget select in custom forms. I tried to mimic the Piccolo array column select and came up with this. These are the changes that should be made. We need to add this line of code to the NewForm.vue InputField like this

<InputField
    v-bind:isFilter="false"
    v-bind:key="columnName"
    v-bind:columnName="String(columnName)"
    v-bind:type="getType(property)"
    v-bind:value="property.default"
    v-bind:choices="property.extra?.choices" // new line
    v-bind:timeResolution="
        schema?.extra?.time_resolution[columnName]
    "
/>

After that, build the Vue frontend and add the dist folder to your local Piccolo Admin installation.
The changes that need to be made to NewStaff model are as follows

# Permission enum is same as before
# with this we mimic Piccolo array column choices
choices = {}
for item in Permission:
    choices[item.name] = {
        "display_name": item.name,
        "value": item.value,
    }

class NewStaff(BaseModel):
    name: t.Annotated[str, Field(max_length=255, pattern=r"^[a-zA-Z\s]+$")]
    email: EmailStr
    superuser: bool
    permissions: t.List[t.Any] = Field(extra={"choices": choices}) # usage of choices

Result is this

enum_select.webm

This isn't perfect, but it might work in your case. I hope you find this useful.

@AmazingAkai
Copy link
Author

Oh interesting, its better than nothing, thanks!

@sinisaos
Copy link
Member

@dantownsend would it be good to add choices option to custom form InputField as in the previous comment? This would allow the user to write custom code to display enums in custom forms (either as a select or an array of select). Something like this

class Permission(str, enum.Enum):
    UPLOADS = "uploads"
    NOTICES = "notices"
    GALLERY = "gallery"
    ADMISSIONS = "admissions"

def custom_form_choices() -> t.Dict[str, t.Any]:
    choices = {}
    for item in Permission:
        choices[item.name] = {
            "display_name": item.name,
            "value": item.value,
        }
    return choices

class NewStaff(BaseModel):
    name: t.Annotated[str, Field(max_length=255, pattern=r"^[a-zA-Z\s]+$")]
    email: EmailStr
    superuser: bool
    permissions: t.Any = Field(  # or permissions: t.List[t.Any] if we want a list of selects as in the previous comment video
        json_schema_extra={"extra": {"choices": custom_form_choices()}}
    )

Result is this

custom_form_select.webm

What do you think about it?

@sinisaos sinisaos reopened this Apr 27, 2024
@AmazingAkai
Copy link
Author

@sinisaos I'm still having the same issue, I'm using piccolo_admin version 1.3.2, I tried installing the github version using pip install git+https://github.com/piccolo-orm/piccolo_admin but I was unable to start the project after installing the dev version.

@dantownsend
Copy link
Member

I wonder if installing it from GitHub doesn't work because the Vue code isn't compiled into static assets.

I'll do a proper release later today.

@dantownsend
Copy link
Member

Try piccolo_admin==1.3.3 - it's now on PyPI.

@sinisaos
Copy link
Member

sinisaos commented May 2, 2024

I wonder if installing it from GitHub doesn't work because the Vue code isn't compiled into static assets.

That exactly the case. If we want to use Piccolo Admin from Github, we need to compile the static files ourselves. With the new release, everything works as expected.
@dantownsend What do you think of the choices from previous comments?

@dantownsend
Copy link
Member

@sinisaos It's an interesting idea. I never considered this before:

permissions: t.Any = Field(  # or permissions: t.List[t.Any] if we want a list of selects as in the previous comment video
        json_schema_extra={"extra": {"choices": custom_form_choices()}}
    )

Is this just a documentation change, or requires other code changes?

@sinisaos
Copy link
Member

sinisaos commented May 3, 2024

@dantownsend Basically the only code change is adding a v-bind:choices="property.extra?.choices" to NewForm.vue InputField. The second change is the usage example in example.py. Here is the PR.

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

No branches or pull requests

3 participants