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

Refactor of interview list page #787

Merged
merged 6 commits into from
Oct 31, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
283 changes: 241 additions & 42 deletions docassemble/AssemblyLine/data/questions/interview_list.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,102 @@
---
# Provide a replacement for the /interviews endpoint in Docassemble
# Provide a replacement for the /interviews endpoint in Docassemble.
# This version is faster than the native version and supports metadata for each interview (including form progress)
comment: |
Customize by:
1. Editing the global configuration (see below), or
2. Including this file and overriding the default values in a replacement YAML file

Relevant options and defaults:

app homepage: https://courtformsonline.org
assembly line:
enable answer sets: True
interview list:
page title: In progress forms # Title of the tab in your browser
page question: In progress forms
page subquestion: null
new form label: Start a new form
new form url: https://courtformsonline.org
logo url: null # Defaults to `app homepage`
logo image url: https://app.yourserver.org/packagestatic/docassemble.AssemblyLine/ma_logo.png
logo image alt: Logo
answer sets title: Answer sets
logo title row 1: null # Defaults to `interview page title`
logo title row 2: null # Defaults to `interview page heading`
exclude from interview list:
- docassemble.AssemblyLine:data/questions/al_saved_sessions_store.yml
- docassemble.AssemblyLine:data/questions/interview_list.yml

interview page title, interview page heading, interview page pre, logo url, interview page url, and new form url
can also be set to a dictionary of languages, like:
interview page title:
en: In progress forms
es: Formularios en progreso

These deprecated configuration options will also be respected at a lower priority:

new form url: https://courtformsonline.org
assembly line:
exclude from interview list:
- docassemble.AssemblyLine:data/questions/al_saved_sessions_store.yml
- docassemble.AssemblyLine:data/questions/al_saved_sessions_store.yml

As will the following options from the global config:
interview page title
interview page heading
interview page pre

Some authors will prefer to customize this page by importing it and overriding the default values
in the YAML file rather than the global configuration. This is slightly more advance than editing
the configuration, but may be just as easy to maintain.

To do this, make a new YAML file and include your custom theme/settings YAML.
It's important to include your theme AFTER the interview list page:

e.g., my_new_interview_list.yml would only need to contain:
---
include:
- docassemble.AssemblyLine:data/questions/interview_list.yml
- docassemble.MyState:my_custom_theme.yml
---
metadata:
title: |
In progress forms
short title: |
In progress forms


Then you would set the following in your global config:
interview list: docassemble.MyState:my_new_interview_list.yml

In some instances, this may be all that is required to use your branding on the
interview list page. You can individually override additional variables as follows:

* PAGE_QUESTION
* PAGE_SUBQUESTION
* NEW_FORM_LABEL
* NEW_FORM_URL
* al_sessions_to_exclude_from_interview_list

The following settings are usually best to leave undefined if you want
the ordinary behavior of your theme:
* PAGE_TITLE
* LOGO_URL
* LOGO_IMAGE_URL
* LOGO_IMAGE_ALT
* LOGO_TITLE_ROW_1
* LOGO_TITLE_ROW_2 (defaults to value from the metadata block)

And of course you can also override the YAML block by block if you want to
further customize it.
---
include:
include:
- docassemble.ALToolbox:display_template.yml
- al_settings.yml
---
# clear playground errors
objects:
- ex: DAEmpty
- AL_ORGANIZATION_HOMEPAGE: DAEmpty
---
features:
small screen navigation: dropdown
Expand All @@ -30,53 +123,111 @@ modules:
- docassemble.ALToolbox.misc
---
objects:
- al_logo: DAStaticFile.using(filename="ma_logo.png", alt_text="Assembly Line Logo")
- al_logo: DAStaticFile.using(filename="ma_logo.png", alt_text="Logo")
---
# Clear some Playground invalid variable reference errors
objects:
- ex: DAEmpty
- interview_metadata: DAEmpty
- other_parties: DAEmpty
- users: DAEmpty
code: |
al_logo.alt_text = "Logo" # Patch for old sessions
---
# This block is a placeholder and will be replaced by the definition below
sections:
- section_in_progress_forms: In progress forms
- section_answer_sets: Answer sets
progressive: False
---
# A code block is the only way to show navigation with custom labels (mako isn't allowed in `sections`)
mandatory: True
code: |
al_logo.alt_text = "Assembly Line Logo"
nav.set_sections(
[
{
"section_in_progress_forms": PAGE_QUESTION or PAGE_TITLE or word("In progress forms")
},
{
"section_answer_sets": ANSWER_SETS_TITLE or word("Answer sets")
}
]
)
---
# These override the `metadata` above
default screen parts:
title: |
% if get_config("interview page title"):
${ get_config("interview page title") }
% else:
% if PAGE_TITLE:
${ PAGE_TITLE }
% elif showifdef("AL_ORGANIZATION_TITLE"):
${ AL_ORGANIZATION_TITLE }
% else:
${ get_config("app name", "CourtFormsOnline") }
% endif
short title: |
% if get_config("interview page title"):
${ get_config("interview page title") }
% else:
% if PAGE_TITLE:
${ PAGE_TITLE }
% elif showifdef("AL_ORGANIZATION_TITLE"):
${ AL_ORGANIZATION_TITLE }
% endif
% else:
${ get_config("app name", "CourtFormsOnline") }
% endif
title url: |
${ all_variables(special='metadata').get('title url', AL_ORGANIZATION_HOMEPAGE) }
% if LOGO_URL:
${ LOGO_URL }
% elif showifdef("AL_ORGANIZATION_HOMEPAGE"):
${ AL_ORGANIZATION_HOMEPAGE }
% else:
% endif:
exit url: |
${ all_variables(special='metadata').get('exit url', AL_ORGANIZATION_HOMEPAGE) }
% if LOGO_URL:
${ LOGO_URL }
% elif showifdef("AL_ORGANIZATION_HOMEPAGE"):
${ AL_ORGANIZATION_HOMEPAGE }
% else:
% endif:
logo: |
<span class="title-container">
<span class="al-logo">
% if LOGO_IMAGE_URL:
<img src="${ LOGO_IMAGE_URL }" alt="${ LOGO_IMAGE_ALT }"/>
% else:
<img src="${ al_logo.url_for() }" alt="${ al_logo.alt_text }"/>
% endif
</span>
<span class="al-title">
<span class="title-row-1">${ AL_ORGANIZATION_TITLE }</span>
<span class="title-row-2">${all_variables(special='metadata').get('title','').rstrip()}</span>
% if LOGO_TITLE_ROW_1:
<span class="title-row-1">${ LOGO_TITLE_ROW_1 }</span>
% elif showifdef("AL_ORGANIZATION_TITLE"):
<span class="title-row-1">${ AL_ORGANIZATION_TITLE }</span>
% else:
<span class="title-row-1">${ get_config("app name", "CourtFormsOnline") }</span>
% endif
% if LOGO_TITLE_ROW_2:
<span class="title-row-2">${ LOGO_TITLE_ROW_2 }</span>
% elif PAGE_QUESTION:
<span class="title-row-2">${ PAGE_QUESTION }</span>
% else:
<span class="title-row-2">${ all_variables(special='metadata').get('title','').rstrip() }</span>
% endif
</span>
</span>
short logo: |
<span class="title-container">
<span class="al-logo">
% if LOGO_IMAGE_URL:
<img src="${ LOGO_IMAGE_URL }" alt="${ LOGO_IMAGE_ALT }"/>
% else:
<img src="${ al_logo.url_for() }" alt="${ al_logo.alt_text }"/>
% endif
</span>
<span class="al-title">
<span class="title-row-1">${ AL_ORGANIZATION_TITLE }</span>
<span class="title-row-2">${ all_variables(special='metadata').get('short title','').rstrip() }</span>
% if PAGE_TITLE:
<span class="title-row-1">${ PAGE_TITLE }</span>
% elif showifdef("AL_ORGANIZATION_TITLE"):
<span class="title-row-1">${ AL_ORGANIZATION_TITLE }</span>
% else:
<span class="title-row-1">${ get_config("app name", "CourtFormsOnline") }</span>
% endif
% if PAGE_QUESTION:
<span class="title-row-2">${ PAGE_QUESTION }</span>
% else:
<span class="title-row-2">${ all_variables(special='metadata').get('title','').rstrip() }</span>
% endif
</span>
</span>
---
Expand All @@ -90,27 +241,19 @@ code: |
nav.hide()
section_in_progress_forms
---
code: |
al_sessions_to_exclude_from_interview_list = get_config("assembly line", {}).get("exclude from interview list")
---
sections:
- section_in_progress_forms: In progress forms
- section_answer_sets: Answer sets
progressive: False
---
event: section_in_progress_forms
id: interview list
question: |
% if get_config("interview page heading"):
${ get_config("interview page heading") }
% if PAGE_QUESTION:
${ PAGE_QUESTION }
% else:
In progress forms
% endif
<span style="float: right;">${ action_button_html(get_config("assembly line",{}).get("new form url", AL_ORGANIZATION_HOMEPAGE), label="Start a new form", icon="plus-circle", color="primary", size="md") }</span>
<span style="float: right;">${ action_button_html(NEW_FORM_URL or showifdef("AL_ORGANIZATION_HOMEPAGE"), label=NEW_FORM_LABEL or word("Start a new form"), icon="plus-circle", color="primary", size="md") }</span>
subquestion: |
% if len(get_saved_interview_list(filename=None, filename_to_exclude=al_session_store_default_filename, exclude_filenames=al_sessions_to_exclude_from_interview_list, exclude_newly_started_sessions=True)) > 0:
% if get_config("interview page pre"):
${ get_config("interview page pre") }
% if PAGE_SUBQUESTION:
${ PAGE_SUBQUESTION }
% else:
Tap the title of a form to keep working on it or to download your completed
documents.
Expand All @@ -136,7 +279,7 @@ section: section_in_progress_forms
under: |
% if len(get_saved_interview_list(filename=None, filename_to_exclude=al_session_store_default_filename, exclude_filenames=al_sessions_to_exclude_from_interview_list)) > 0:
<div style="float: right;">
${ action_button_html(url_action("interview_list_delete_all"), label="Delete All", size="md", color="danger", icon="trash-can", id_tag="al-delete-all-sessions") }
${ action_button_html(url_action("interview_list_delete_all"), label=word("Delete All"), size="md", color="danger", icon="trash-can", id_tag="al-delete-all-sessions") }
</div>
% endif
script:
Expand All @@ -162,13 +305,17 @@ script:
event: section_answer_sets
id: answer set list
question: |
Answer sets <span style="float: right;">${ action_button_html(get_config("assembly line",{}).get("new form url", AL_ORGANIZATION_HOMEPAGE), label="Start a new form", icon="plus-circle", color="primary", size="md") }</span>
% if ANSWER_SETS_TITLE:
${ ANSWER_SETS_TITLE }
% else:
Answer sets
% endif
<span style="float: right;">${ action_button_html(NEW_FORM_URL or showifdef("AL_ORGANIZATION_HOMEPAGE"), label=NEW_FORM_LABEL or word("Start a new form"), icon="plus-circle", color="primary", size="md") }</span>
subquestion: |
View, delete, or rename your answer sets below. To copy an answer set into a
new form:

1. [Start a new
form](${ get_config("assembly line",{}).get("new form url", AL_ORGANIZATION_HOMEPAGE) })
1. [${ NEW_FORM_LABEL or "Start a new form"}](${ NEW_FORM_URL or showifdef("AL_ORGANIZATION_HOMEPAGE") })
1. Then, use the menu to load your answer set.

${ interview_list_html(view_only=True, delete_action="interview_list_delete_session", exclude_newly_started_sessions=False) }
Expand Down Expand Up @@ -239,4 +386,56 @@ code: |
except Exception as ex:
log("Problem deleting answers", "danger")
log(f"Problem deleting answers for a user: {ex}")
interview_list_delete_all = True
interview_list_delete_all = True
---
########### Get customized text values from configuration file ###################################33
---
code: |
def config_with_language_fallback(config_key, top_level_config_key=None):
interview_list_config = get_config("assembly line",{}).get("interview list",{})
if interview_list_config.get(config_key):
if isinstance(interview_list_config.get(config_key), dict):
if get_language() in interview_list_config.get(config_key):
return interview_list_config.get(config_key)[get_language()]
else:
return next(iter(interview_list_config.get(config_key).values()), None)
else:
return interview_list_config.get(config_key)
else:
return get_config(top_level_config_key or config_key)
---
code: |
PAGE_TITLE = config_with_language_fallback("page title", "interview page title")
---
code: |
PAGE_QUESTION = config_with_language_fallback("page question", "interview page heading")
---
code: |
PAGE_SUBQUESTION = config_with_language_fallback("interview page pre")
---
code: |
LOGO_URL = config_with_language_fallback("logo url", "app homepage")
---
code: |
LOGO_IMAGE_URL = config_with_language_fallback("logo image url")
---
code: |
LOGO_IMAGE_ALT = config_with_language_fallback("logo alt")
---
code: |
NEW_FORM_LABEL = config_with_language_fallback("new form label")
---
code: |
NEW_FORM_URL = config_with_language_fallback("new form url", "app homepage")
---
code: |
ANSWER_SETS_TITLE = config_with_language_fallback("answer sets title")
---
code: |
LOGO_TITLE_ROW_1 = config_with_language_fallback("logo title row 1")
---
code: |
LOGO_TITLE_ROW_2 = config_with_language_fallback("logo title row 2")

---
code: al_sessions_to_exclude_from_interview_list = get_config("assembly line",{}).get("interview list",{}).get("exclude from interview list", get_config("assembly line",{}).get("exclude from interview list"))