diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-18 08:50:02 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-18 08:50:02 +0200 |
| commit | c9bf881ba455a321928d8c49deafca13dc662ab6 (patch) | |
| tree | 24ec4dddc8f271b9460ebe37231c13109a5758d8 /clients | |
| parent | 702d9327e5f979deff392dceeced2dd16d1203e1 (diff) | |
| download | bokf-e0ffdc1503e62c3e3d6c849c4bdabbd8a0c50122.tar.gz bokf-e0ffdc1503e62c3e3d6c849c4bdabbd8a0c50122.zip | |
bokftui: Ctrl+R reloads the binary and restores session, year and viewv0.1.8
Diffstat (limited to 'clients')
| -rw-r--r-- | clients/bokftui.c | 134 |
1 files changed, 122 insertions, 12 deletions
diff --git a/clients/bokftui.c b/clients/bokftui.c index ccbce14..a8b582c 100644 --- a/clients/bokftui.c +++ b/clients/bokftui.c @@ -1,4 +1,5 @@ #include <dirent.h> +#include <errno.h> #include <locale.h> #include <math.h> #include <ncursesw/ncurses.h> @@ -20,6 +21,10 @@ #define KEY_CTRL_N 0x0e /* Ctrl+C quits the application; Esc is navigation only */ static int g_quit = 0; +/* Ctrl+R re-execs the binary, keeping session, org, year and screen */ +static int g_reload = 0; +static char g_scene[32] = "dashboard"; +static char g_reload_scene[32]; static int ui_getch(void) { @@ -28,6 +33,11 @@ static int ui_getch(void) g_quit = 1; return 27; /* behave like "back" so screens unwind */ } + if (ch == 18) { /* Ctrl+R */ + g_reload = 1; + snprintf(g_reload_scene, sizeof g_reload_scene, "%s", g_scene); + return 27; + } return ch; } @@ -411,8 +421,10 @@ static void frame(const char *title) static void hints(const char *s) { + char line[512]; + snprintf(line, sizeof line, "%s ^R = ladda om", s); attron(A_DIM); - mvaddstr(LINES - 1, 2, s); + mvaddstr(LINES - 1, 2, line); attroff(A_DIM); clrtoeol(); } @@ -3933,6 +3945,52 @@ static void templates_screen(struct app *a) } } +/* Screen names for Ctrl+R restoration and --screen. Only the top-level + views; sub-screens unwind to their parent. */ +static void open_scene(struct app *a, const char *scene) +{ + snprintf(g_scene, sizeof g_scene, "%s", scene); + if (strcmp(scene, "vouchers") == 0) + vouchers_screen(a); + else if (strcmp(scene, "inbox") == 0) + inbox_screen(a); + else if (strcmp(scene, "ib") == 0) + ib_screen(a); + else if (strcmp(scene, "templates") == 0) + templates_screen(a); + else if (strcmp(scene, "reports") == 0) + reports_screen(a); + else if (strcmp(scene, "audit") == 0) + audit_screen(a); + else if (strcmp(scene, "settings") == 0) + settings_screen(a); + else if (strcmp(scene, "company") == 0) + company_screen(a); +} + +static void do_reload(struct app *a, const char *self) +{ + char orgbuf[32], fybuf[32]; + char *argv[12]; + int n = 0; + snprintf(orgbuf, sizeof orgbuf, "%lld", (long long)a->org); + snprintf(fybuf, sizeof fybuf, "%lld", (long long)a->fy); + argv[n++] = (char *)(self && *self ? self : "bokftui"); + argv[n++] = "--org"; + argv[n++] = orgbuf; + if (a->fy > 0) { + argv[n++] = "--fy"; + argv[n++] = fybuf; + } + argv[n++] = "--screen"; + argv[n++] = g_reload_scene[0] ? g_reload_scene : g_scene; + argv[n] = NULL; + setenv("BOKFD_SESSION", a->session, 1); + endwin(); + execvp(argv[0], argv); + fprintf(stderr, "bokftui: kunde inte ladda om: %s\n", strerror(errno)); +} + static const char *const MAIN_ITEMS[] = { "Verifikat", "Underlag (inkorg)", "IngÄende balans", "Mallar", "Rapporter", "Revision", @@ -3944,6 +4002,7 @@ static void dashboard(struct app *a) { for (;;) { int sel = menu("Bokf", MAIN_ITEMS, 10, 1); + snprintf(g_scene, sizeof g_scene, "%s", "dashboard"); if (g_quit) return; if (sel == -4) { @@ -3956,28 +4015,28 @@ static void dashboard(struct app *a) continue; /* Esc/back at the top level never exits */ switch (sel) { case 0: - vouchers_screen(a); + open_scene(a, "vouchers"); break; case 1: - inbox_screen(a); + open_scene(a, "inbox"); break; case 2: - ib_screen(a); + open_scene(a, "ib"); break; case 3: - templates_screen(a); + open_scene(a, "templates"); break; case 4: - reports_screen(a); + open_scene(a, "reports"); break; case 5: - audit_screen(a); + open_scene(a, "audit"); break; case 6: - settings_screen(a); + open_scene(a, "settings"); break; case 7: - company_screen(a); + open_scene(a, "company"); break; case 8: select_fiscal_year(a); @@ -4274,6 +4333,10 @@ static void usage(FILE *f) " --socket TARGET unix path, tcp:host:port or tls:host:port\n" " --user NAME prefill username\n" " --org ID select org directly\n" + " --fy ID select fiscal year directly\n" + " --session ID reuse an open session (or BOKFD_SESSION)\n" + " --screen NAME start in a view: dashboard, vouchers, inbox,\n" + " ib, templates, reports, audit, settings, company\n" " --version\n"); } @@ -4282,13 +4345,21 @@ int main(int argc, char **argv) struct app app; memset(&app, 0, sizeof app); app.conn.fd = -1; - const char *cli_socket = NULL, *cli_user = NULL; - int64_t want_org = 0; + const char *self = argc > 0 ? argv[0] : "bokftui"; + const char *cli_socket = NULL, *cli_user = NULL, *cli_session = NULL; + const char *screen_arg = NULL; + int64_t want_org = 0, want_fy = 0; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--socket") == 0 && i + 1 < argc) cli_socket = argv[++i]; else if (strcmp(argv[i], "--user") == 0 && i + 1 < argc) cli_user = argv[++i]; + else if (strcmp(argv[i], "--session") == 0 && i + 1 < argc) + cli_session = argv[++i]; + else if (strcmp(argv[i], "--screen") == 0 && i + 1 < argc) + screen_arg = argv[++i]; + else if (strcmp(argv[i], "--fy") == 0 && i + 1 < argc) + want_fy = strtoll(argv[++i], NULL, 10); else if (strcmp(argv[i], "--org") == 0 && i + 1 < argc) { want_org = strtoll(argv[++i], NULL, 10); } else if (strcmp(argv[i], "--version") == 0) { @@ -4325,8 +4396,21 @@ int main(int argc, char **argv) keypad(stdscr, TRUE); curs_set(1); + const char *env_session = getenv("BOKFD_SESSION"); + const char *session_arg = cli_session ? cli_session : env_session; + if (session_arg && *session_arg && + client_connect(app.socket, &app.conn) == 0) { + char *resp = + client_rpc(&app.conn, "session.whoami", session_arg, 0, NULL); + if (resp && client_ok(resp)) + snprintf(app.session, sizeof app.session, "%s", session_arg); + else + client_close(&app.conn); + free(resp); + } + const char *token = getenv("BOKFD_TOKEN"); - if (token && *token) { + if (!app.session[0] && token && *token) { char *err = NULL; if (try_login(&app, NULL, NULL, token, &err) == 0) { config_save(&app); @@ -4348,9 +4432,35 @@ int main(int argc, char **argv) return 0; } app_refresh_context(&app); + if (want_fy > 0) { + char args[64]; + snprintf(args, sizeof args, "{\"id\":%lld}", (long long)want_fy); + char *resp = client_rpc(&app.conn, "fiscal_year.get", app.session, + app.org, args); + if (resp && client_ok(resp)) { + app.fy = want_fy; + char *label = jstr_dup(resp, "result.label"); + char *start = jstr_dup(resp, "result.start_date"); + char *end = jstr_dup(resp, "result.end_date"); + if (label) + snprintf(app.fy_label, sizeof app.fy_label, "%s", label); + if (start) + snprintf(app.fy_start, sizeof app.fy_start, "%s", start); + if (end) + snprintf(app.fy_end, sizeof app.fy_end, "%s", end); + free(label); + free(start); + free(end); + } + free(resp); + } update_status(&app); + if (screen_arg && *screen_arg && strcmp(screen_arg, "dashboard") != 0) + open_scene(&app, screen_arg); dashboard(&app); + if (g_reload) + do_reload(&app, self); client_rpc(&app.conn, "session.close", app.session, 0, "{}"); acct_cache_free(); client_close(&app.conn); |
