Skip to main content

Issue Tracker

Implement a simple issue tracker using a table to create master-detail views.

from h2o_wave import main, app, Q, ui
from faker import Faker

fake = Faker()

_id = 0


class Issue:
def __init__(self, text: str, status: str):
global _id
_id += 1
self.id = f'I{_id}'
self.text = text
self.status = status
self.views = 0


# Create some issues
issues = [Issue(text=fake.sentence(), status='Open') for i in range(12)]

# Build a lookup of issues for convenience
issue_lookup = {issue.id: issue for issue in issues}

# Create columns for our issue table.
columns = [
ui.table_column(name='text', label='Issue'),
ui.table_column(name='status', label='Status'),
ui.table_column(name='views', label='Views'),
]


def make_issue_table(allow_multiple_selection=False):
return ui.table(
name='issues',
columns=columns,
rows=[ui.table_row(name=issue.id, cells=[issue.text, issue.status, str(issue.views)]) for issue in issues],
multiple=allow_multiple_selection
)


async def edit_multiple(q: Q):
q.page['form'] = ui.form_card(
box='1 1 6 7',
items=[
make_issue_table(allow_multiple_selection=True), # This time, allow multiple selections
ui.buttons([
ui.button(name='reopen_issues', label='Reopen Selected', primary=True),
ui.button(name='close_issues', label='Close Selected', primary=True),
ui.button(name='back', label='Back to safety')
]),
]
)
await q.page.save()


async def show_issues(q: Q):
q.page['form'] = ui.form_card(
box='1 1 4 7',
items=[
make_issue_table(),
ui.buttons([ui.button(name='edit_multiple', label='Edit Multiple...', primary=True)]),
]
)
await q.page.save()


async def show_issue(q: Q, issue_id: str):
issue = issue_lookup[issue_id]
issue.views += 1

q.client.active_issue_id = issue_id

q.page['form'] = ui.form_card(
box='1 1 4 4',
items=[
ui.text_xl(f'Issue {issue.id}'),
ui.text(issue.text),
ui.text_xs(f'({issue.views} views)'),
ui.buttons([
ui.button(
name='close_issue' if issue.status == 'Open' else 'reopen_issue',
label="Close Issue" if issue.status == 'Open' else "Reopen Issue",
primary=True,
),
ui.button(name='back', label='Back'),
]),
]
)

await q.page.save()


async def close_issue(q: Q):
issue = issue_lookup[q.client.active_issue_id]
issue.status = 'Closed'
await show_issues(q)


async def close_issues(q: Q):
for issue_id in q.args.issues:
issue = issue_lookup[issue_id]
issue.status = 'Closed'
await show_issues(q)


async def reopen_issue(q: Q):
issue = issue_lookup[q.client.active_issue_id]
issue.status = 'Open'
await show_issues(q)


async def reopen_issues(q: Q):
for issue_id in q.args.issues:
issue = issue_lookup[issue_id]
issue.status = 'Open'
await show_issues(q)


@app('/demo')
async def serve(q: Q):
if q.args.edit_multiple:
await edit_multiple(q)
elif q.args.reopen_issues:
await reopen_issues(q)
elif q.args.close_issues:
await close_issues(q)
elif q.args.reopen_issue:
await reopen_issue(q)
elif q.args.close_issue:
await close_issue(q)
elif q.args.issues: # An issue was clicked on
await show_issue(q, q.args.issues[0])
else:
await show_issues(q)

Tags:  table