From ecd84a40e4b9190aa940cc5127e0641697ad87a9 Mon Sep 17 00:00:00 2001 From: nojhan Date: Sun, 30 Jul 2023 10:24:10 +0200 Subject: [PATCH] feat: highlight last touched task - fix promote/demote --- .klyban.csv | 3 +++ klyban.py | 29 ++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.klyban.csv b/.klyban.csv index 4e639f9..8597fa5 100644 --- a/.klyban.csv +++ b/.klyban.csv @@ -10,3 +10,6 @@ 10,"DONE","fix delete","'delete' print the kanban not updated","bug","","2023-07-29T17:48:14.950376" 11,"TODO","fix quotes","After 'add', empty columns got remaining quotes.","bug","","2023-07-29T17:49:33.862442" 12,"TODO","multiple select","Allow to pass several IDs or ranges to commands.","feat","","2023-07-29T17:49:05.411800" +13,"TODO","card widgets","Refactor into cards/list of cards with widget classes.","feat,UX","","2023-07-30T10:12:18.299798" +14,"DONE","highlight last action","Use a virtual hint column to point to the last touched task.","feat,UX","","2023-07-30T10:20:36.795048" +15,"TODO","hide old done tasks","Hide tasks with last status that haven't been touched since a long time.","feat","","2023-07-30T10:16:39.517669" diff --git a/klyban.py b/klyban.py index af4b3f5..036d64a 100644 --- a/klyban.py +++ b/klyban.py @@ -59,6 +59,8 @@ def load_data(context): df = df.replace(r'^[\s"\']*$', np.nan, regex=True) finally: + # Virtual "hints" column. + df['H'] = '' if context.obj['debug']: print("Loaded:") print(df) @@ -71,6 +73,9 @@ def save_data(context, df): print(df) # FIXME double check that there are actually data. + # Remove the virtual "hints" column. + df = df.drop('H', axis = 1) + # Bring back ID as a regular column. df = df.reset_index() @@ -126,6 +131,7 @@ def check_id(context, param, value): # Display options. @click.option('-H','--show-headers', is_flag=True, help="Show the headers.") @click.option('-S', '--show-keys' , default='ID,TITLE,DETAILS,TAGS', type=str , show_default=True, help="Comma-separated, ordered list of fields that should be shown (use 'all' for everything).") +@click.option('-G', '--highlight', type = int, default = None, help="Highlight a specific task.") # Low-level configuration options. @click.option('--status-key' , default='STATUS' , type=str, show_default=True, help="Header key defining the status of tasks.") @click.option('--status-list' , default='TODO,DOING,HOLD,DONE', type=str, show_default=True, help="Comma-separated, ordered list of possible values for the status of tasks.") @@ -147,6 +153,7 @@ def cli(context, **kwargs): context.obj['input'] = kwargs['input'] context.obj['show_headers'] = kwargs['show_headers'] + context.obj['highlight'] = kwargs['highlight'] context.obj['id_key'] = kwargs['id_key'] context.obj['status_key'] = kwargs['status_key'] @@ -170,6 +177,9 @@ def cli(context, **kwargs): else: context.obj['show_keys'] = kwargs['show_keys'].split(',') + # Always show the 'Hint' column. + context.obj['show_keys'] = ['H'] + context.obj['show_keys'] + context.obj['debug'] = kwargs['debug'] # At the end, always load data, whatever the command will be. @@ -196,6 +206,9 @@ def show(context, tid): print("No task.") return + if context.obj['highlight'] is not None: + df.loc[context.obj['highlight'], 'H'] = ':arrow_forward:' + # Group by status. tables = df.groupby(context.obj['status_key']) # Loop over the asked ordered status groups. @@ -273,9 +286,9 @@ def show(context, tid): @cli.command() @click.argument('TITLE', required=True, nargs=-1) -@click.option('-d', '--details' , type=str, default=None, prompt=True) -@click.option('-t', '--tags' , type=str, default=None, prompt=True) -@click.option('-a', '--deadline', type=str, default=None, prompt=True) +@click.option('-d', '--details' , type=str, prompt=True) +@click.option('-t', '--tags' , type=str, prompt=True) +@click.option('-a', '--deadline', type=str, prompt=True) @click.option('-s', '--status' , type=str, default='TODO') @click.pass_context def add(context, title, status, details, tags, deadline): @@ -285,6 +298,7 @@ def add(context, title, status, details, tags, deadline): next_id = 0 else: next_id = df.index.max() + 1 + df.loc[next_id] = pd.Series({ context.obj['status_key']: status, context.obj['title_key']: " ".join(title), @@ -296,6 +310,7 @@ def add(context, title, status, details, tags, deadline): save_data(context,df) + context.obj['highlight'] = next_id context.invoke(show) @@ -336,6 +351,7 @@ def edit(context, tid, title, status, details, tags, deadline): }) save_data(context,df) + context.obj['highlight'] = tid context.invoke(show) @@ -387,6 +403,7 @@ def status(context, tid, status): change_status(context, tid, status) + context.obj['highlight'] = tid context.invoke(show) @@ -406,7 +423,7 @@ def promote(context, tid): i=0 for i in range(len(context.obj['status_list'])): - if row[context.obj['status_key']][1] == context.obj['status_list'][i]: + if row[context.obj['status_key']] == context.obj['status_list'][i]: break else: i += 1 @@ -415,6 +432,7 @@ def promote(context, tid): else: change_status(context, tid, context.obj['status_list'][i+1]) + context.obj['highlight'] = tid context.invoke(show) @@ -434,7 +452,7 @@ def demote(context, tid): i=0 for i in range(len(context.obj['status_list'])): - if row[context.obj['status_key']][1] == context.obj['status_list'][i]: + if row[context.obj['status_key']] == context.obj['status_list'][i]: break else: i += 1 @@ -443,6 +461,7 @@ def demote(context, tid): else: change_status(context, tid, context.obj['status_list'][i-1]) + context.obj['highlight'] = tid context.invoke(show)