Download app/ui/layout.py from killvung/cfy: direct link, hf CLI and curl.
- Browser
- Download file 6.24 kB
-
https://huggingface.co/spaces/killvung/cfy/resolve/main/app/ui/layout.py
- Command line
-
hf download hf://spaces/killvung/cfy/app/ui/layout.py
-
curl -L -o layout.py https://huggingface.co/spaces/killvung/cfy/resolve/main/app/ui/layout.py
6.24 kB
| """Review UI component tree (Gradio Blocks layout).""" | |
| from __future__ import annotations | |
| from dataclasses import dataclass, field | |
| import gradio as gr | |
| from app.render import CANDIDATE_COUNT, OUTPUT_KEYS | |
| from app.styles import ( | |
| ACCEPTED_COUNT_INITIAL, | |
| APP_TITLE, | |
| BTN_ALL_DONE, | |
| BTN_CONTINUE, | |
| BTN_GO_BACK, | |
| BTN_PREVIOUS, | |
| BTN_SELECT, | |
| CAT_SUBTEXT, | |
| COMPLETE_HEADING, | |
| PRIMARY_INSTRUCTION, | |
| ) | |
| def _candidate_image() -> gr.Image: | |
| return gr.Image( | |
| interactive=False, | |
| show_label=False, | |
| container=False, | |
| buttons=[], | |
| elem_classes=["candidate-photo"], | |
| ) | |
| def _build_card_row( | |
| slots: tuple[int, ...], | |
| ) -> tuple[list[gr.Image], list[gr.Column], list[gr.Button]]: | |
| images: list[gr.Image] = [] | |
| cards: list[gr.Column] = [] | |
| select_buttons: list[gr.Button] = [] | |
| with gr.Row(elem_classes=["grid-row"]): | |
| for slot in slots: | |
| with gr.Column(elem_classes=["card-col"]) as card_col: | |
| cards.append(card_col) | |
| gr.Markdown(f"**Candidate {slot}**", elem_classes=["candidate-label"]) | |
| images.append(_candidate_image()) | |
| select_buttons.append( | |
| gr.Button(BTN_SELECT, elem_classes=["select-btn", "select-btn-off"]) | |
| ) | |
| return images, cards, select_buttons | |
| class ReviewUI: | |
| """Registry of all Gradio components for the review app.""" | |
| ctx: gr.State | |
| task: gr.State | |
| selections: gr.State | |
| error_panel: gr.Markdown | |
| review_screen: gr.Column | |
| complete_screen: gr.Column | |
| cat_heading: gr.Markdown | |
| progress: gr.Markdown | |
| images: list[gr.Image] = field(default_factory=list) | |
| cards: list[gr.Column] = field(default_factory=list) | |
| select_buttons: list[gr.Button] = field(default_factory=list) | |
| accepted_count: gr.Markdown | None = None | |
| status_message: gr.Markdown | None = None | |
| primary_btn: gr.Button | None = None | |
| prev_btn: gr.Button | None = None | |
| all_done_nav_btn: gr.Button | None = None | |
| all_done_extra_btn: gr.Button | None = None | |
| go_back_btn: gr.Button | None = None | |
| _components: dict[str, gr.components.Component] = field(default_factory=dict, repr=False) | |
| def state_inputs(self) -> list[gr.State]: | |
| return [self.ctx, self.task, self.selections] | |
| def outputs(self) -> list[gr.components.Component]: | |
| return [self._components[key] for key in OUTPUT_KEYS] | |
| def build(cls) -> ReviewUI: | |
| ctx_state = gr.State(None) | |
| task_state = gr.State(None) | |
| selections_state = gr.State([False] * CANDIDATE_COUNT) | |
| gr.Markdown(f"# {APP_TITLE}", elem_classes=["review-header"]) | |
| gr.Markdown(PRIMARY_INSTRUCTION, elem_classes=["review-header"]) | |
| error_panel = gr.Markdown("", elem_classes=["error-banner"], visible=False) | |
| with gr.Column(visible=False) as review_screen: | |
| with gr.Column(elem_classes=["review-body"]): | |
| with gr.Column(elem_classes=["cat-block"]): | |
| cat_heading = gr.Markdown("") | |
| gr.Markdown(CAT_SUBTEXT) | |
| progress = gr.Markdown("") | |
| row1_images, row1_cards, row1_buttons = _build_card_row((1, 2)) | |
| row2_images, row2_cards, row2_buttons = _build_card_row((3, 4)) | |
| images = row1_images + row2_images | |
| cards = row1_cards + row2_cards | |
| select_buttons = row1_buttons + row2_buttons | |
| accepted_count = gr.Markdown( | |
| ACCEPTED_COUNT_INITIAL, elem_classes=["accepted-count"] | |
| ) | |
| status_message = gr.Markdown("", elem_classes=["status-message"]) | |
| with gr.Row(elem_classes=["actions-row"]): | |
| prev_btn = gr.Button( | |
| BTN_PREVIOUS, elem_classes=["secondary-btn"], visible=False | |
| ) | |
| primary_btn = gr.Button(BTN_CONTINUE, elem_classes=["primary-btn"]) | |
| all_done_nav_btn = gr.Button( | |
| BTN_ALL_DONE, elem_classes=["secondary-btn"], visible=False | |
| ) | |
| all_done_extra_btn = gr.Button( | |
| BTN_ALL_DONE, elem_classes=["all-done-row"], visible=False | |
| ) | |
| with gr.Column(visible=False) as complete_screen: | |
| gr.Markdown(COMPLETE_HEADING, elem_classes=["complete-box"]) | |
| with gr.Row(elem_classes=["complete-actions"]): | |
| go_back_btn = gr.Button(BTN_GO_BACK, elem_classes=["secondary-btn"]) | |
| components = { | |
| "ctx": ctx_state, | |
| "task": task_state, | |
| "selections": selections_state, | |
| "error_panel": error_panel, | |
| "review_screen": review_screen, | |
| "complete_screen": complete_screen, | |
| "cat_heading": cat_heading, | |
| "progress": progress, | |
| **{f"image_{index}": images[index] for index in range(CANDIDATE_COUNT)}, | |
| **{f"card_{index}": cards[index] for index in range(CANDIDATE_COUNT)}, | |
| **{f"select_{index}": select_buttons[index] for index in range(CANDIDATE_COUNT)}, | |
| "accepted_count": accepted_count, | |
| "status_message": status_message, | |
| "primary_btn": primary_btn, | |
| "prev_btn": prev_btn, | |
| "all_done_nav_btn": all_done_nav_btn, | |
| "all_done_extra_btn": all_done_extra_btn, | |
| } | |
| return cls( | |
| ctx=ctx_state, | |
| task=task_state, | |
| selections=selections_state, | |
| error_panel=error_panel, | |
| review_screen=review_screen, | |
| complete_screen=complete_screen, | |
| cat_heading=cat_heading, | |
| progress=progress, | |
| images=images, | |
| cards=cards, | |
| select_buttons=select_buttons, | |
| accepted_count=accepted_count, | |
| status_message=status_message, | |
| primary_btn=primary_btn, | |
| prev_btn=prev_btn, | |
| all_done_nav_btn=all_done_nav_btn, | |
| all_done_extra_btn=all_done_extra_btn, | |
| go_back_btn=go_back_btn, | |
| _components=components, | |
| ) | |