shared/screens/initial/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
mod append_previous_connection;
mod append_previous_credentials_result;
mod influx_buckets_connection_test;
mod influx_buckets_connection_test_response;
mod load_previous_connections;
mod load_previous_connections_result;
mod load_settings_screen;
mod quick_actions_load;
mod quick_actions_load_result;
mod quick_actions_user_selected;
mod set_api_token;
mod set_base_url;
mod user_selected_previous_connection;

use crate::capabilities::persistent_storage::PersistentStorageOutput;
use crate::internal_error_strings::N008_USED;
use crate::model::{Model, Screens};
use crate::model_ui::screens_common::remote_multi_choice::multi_choice::UiStringIndex;
use crate::screens::initial::influx_buckets_connection_test::influx_bucket_connection_test;
use crate::screens::initial::influx_buckets_connection_test_response::influx_buckets_connection_test_response;
use crate::screens::initial::load_previous_connections::load_previous_connections;
use crate::screens::initial::load_previous_connections_result::load_previous_connections_result;
use crate::screens::initial::load_settings_screen::load_settings_screen;
use crate::screens::initial::quick_actions_load::load_quick_actions;
use crate::screens::initial::quick_actions_load_result::load_quick_actions_result;
use crate::screens::initial::quick_actions_user_selected::quick_actions_user_selected;
use crate::screens::initial::set_api_token::set_api_token;
use crate::screens::initial::set_base_url::set_base_url;
use crate::screens::initial::user_selected_previous_connection::user_selected_previous_connection;
use crate::screens::input_fields_and_tags::RemoteResource;
use crate::screens::select_org_bucket_measurements::influx_get_orgs_response::Org;
use crate::screens_common::model::field_type::UserFieldValue;
use crate::screens_common::model::multi_choice::MultiChoice;
use crate::screens_common::model::previous_connection::PreviousConnection;
use crate::screens_common::requests::BucketsResult;
use crate::{Effect, Event};
use crux_core::Command;
use crux_http::http::Url;
use log::{error, trace, Level};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt::{Display, Formatter};
// ============================================================================
// Screen data.
// ============================================================================

#[derive(Default, Clone, Debug)]
pub struct InitialScreenData {
    pub api_token: Option<String>,
    pub base_url: Option<String>,
    pub quick_actions: RemoteResource<MultiChoice<QuickAction>>,
    pub previous_connections: RemoteResource<MultiChoice<PreviousConnection>>,
    pub failed_to_contact_influx: bool,
}

/// Saved connection and values for quick entry of similar items
/// if a tag is None we will need to fetch available tags on load
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct QuickAction {
    pub name: String,
    pub api_token: String,
    pub base_url: Url,
    pub org: Org,
    pub bucket: String,
    pub measurement: String,
    pub tags: BTreeMap<String, Option<String>>,
    pub fields: BTreeMap<String, UserFieldValue>,
}

impl Display for QuickAction {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.name)
    }
}

// ============================================================================
// Screen event data.
// ============================================================================

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum ScEvInitial {
    // persisting credentials to disk, todo consider an encryption idea
    AppendPreviousConnection(PreviousConnection),
    #[serde(skip)]
    AppendPreviousConnectionResult(PersistentStorageOutput),
    InfluxBucketsConnectionTest,
    #[serde(skip)]
    InfluxBucketsConnectionTestResponse(crux_http::Result<crux_http::Response<BucketsResult>>),
    LoadPreviousConnections,
    #[serde(skip)]
    LoadPreviousConnectionsResult(PersistentStorageOutput),
    QuickActionsLoad,
    #[serde(skip)]
    QuickActionsLoadResult(PersistentStorageOutput),
    QuickActionsUserSelected(UiStringIndex),
    LoadSettingsScreen,
    SetApiToken(String),
    SetBaseUrl(String),
    /// User selected a previous connection string being the index of the selection
    UserSelectedPreviousConnection(UiStringIndex),
}

// ============================================================================
// Screen event processing.
// ============================================================================

pub fn initial_screen_events(
    initial_screen_event: ScEvInitial,
    model: &mut Model,
) -> Command<Effect, Event> {
    trace!("Initial screen event: Validating model");

    let Screens::InitialScreen(ref mut screen_data) = model.screen else {
        error!("Screen was in an unexpected state {:?}", model.screen);
        model.user_messages.error_report_to_developer(N008_USED);
        model
            .user_messages
            .add_message("Unrecoverable internal error state", Level::Error);
        trace!("initial_screen_events: Returning crux_core::render::render()");
        return crux_core::render::render();
    };

    trace!("running initial screen event");

    // ordered alphabetically to line up with filesystem
    match initial_screen_event {
        ScEvInitial::InfluxBucketsConnectionTest => influx_bucket_connection_test(
            &mut model.screen,
            &mut model.user_messages,
            &mut model.example_data,
        ),
        ScEvInitial::InfluxBucketsConnectionTestResponse(bucket_result) => {
            // todo I am acting on the response here but not checking its valid...
            // append_previous_connection(screen_data, &mut model.user_messages, caps); // save connection
            influx_buckets_connection_test_response(
                &mut model.screen,
                &mut model.user_messages,
                bucket_result,
            )
        }
        ScEvInitial::SetApiToken(api_token) => set_api_token(screen_data, api_token),
        ScEvInitial::SetBaseUrl(base_url) => set_base_url(screen_data, base_url),
        ScEvInitial::AppendPreviousConnection(_) => Command::done(), // todo
        ScEvInitial::AppendPreviousConnectionResult(_) => Command::done(), // todo
        ScEvInitial::LoadPreviousConnections => load_previous_connections(),
        ScEvInitial::LoadPreviousConnectionsResult(file) => {
            load_previous_connections_result(screen_data, &mut model.user_messages, file)
        }
        ScEvInitial::UserSelectedPreviousConnection(index) => user_selected_previous_connection(
            index,
            &mut model.screen,
            &mut model.user_messages,
            &mut model.example_data,
        ),
        ScEvInitial::LoadSettingsScreen => load_settings_screen(&mut model.screen),
        ScEvInitial::QuickActionsLoad => load_quick_actions(),
        ScEvInitial::QuickActionsLoadResult(data) => {
            load_quick_actions_result(screen_data, &mut model.user_messages, data)
        }
        ScEvInitial::QuickActionsUserSelected(string_index) => {
            quick_actions_user_selected(string_index, model)
        }
    }
}