diff --git a/.cargo/config.toml b/.cargo/config.toml index 41b5e65e..3e8d1938 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,3 +1,6 @@ +[net] +offline = true + # Faster linking for local dev rebuilds. # Uses lld instead of the default bfd linker; requires `lld` from the flake # devShell. Run `direnv reload` after changing flake.nix. diff --git a/client-gui2 b/client-gui2 index 4cf770b9..09dd5432 160000 --- a/client-gui2 +++ b/client-gui2 @@ -1 +1 @@ -Subproject commit 4cf770b95619a4666b7d75c78001383c7c63ce06 +Subproject commit 09dd543243fc720b1737cb4fa950586c80949726 diff --git a/common/build.rs b/common/build.rs index be1b9b59..a8a51dd0 100644 --- a/common/build.rs +++ b/common/build.rs @@ -8,6 +8,7 @@ fn main() -> Result<(), Box> { // here makes the root common crate usable by TUI and Tauri alike. .type_attribute(".komp_ac.accounting", serde) .type_attribute(".komp_ac.analytics", serde) + .field_attribute(".komp_ac.analytics.ReportDashboardFilter.primary", "#[serde(default)]") .type_attribute(".komp_ac.auth", serde) .type_attribute(".komp_ac.common", serde) .type_attribute(".komp_ac.document_data", serde) diff --git a/common/proto/analytics.proto b/common/proto/analytics.proto index 5948d6a0..abc1b054 100644 --- a/common/proto/analytics.proto +++ b/common/proto/analytics.proto @@ -281,6 +281,28 @@ message ReportFilterTarget { message ReportDashboardFilter { ReportParameter parameter = 1; repeated ReportFilterTarget targets = 2; + bool primary = 3; +} + +enum ReportPeriodBoundary { + REPORT_PERIOD_BOUNDARY_UNSPECIFIED = 0; + REPORT_PERIOD_BOUNDARY_INCLUSIVE = 1; + REPORT_PERIOD_BOUNDARY_EXCLUSIVE = 2; +} + +message ReportDateRange { + string start_filter = 1; + string end_filter = 2; + ReportPeriodBoundary end_boundary = 3; +} + +message ReportPeriod { + string date_basis = 1; + oneof selection { + ReportDateRange date_range = 2; + string accounting_period_filter = 3; + string as_of_filter = 4; + } } message ReportActionBinding { @@ -353,6 +375,7 @@ message ReportDashboardDefinition { repeated ReportGrant grants = 5; uint32 refresh_seconds = 6; repeated ReportDatasetVersionRef dataset_versions = 7; + ReportPeriod period = 8; } message ReportDatasetVersionRef { diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index b4f761dd..a95be341 100644 Binary files a/common/src/proto/descriptor.bin and b/common/src/proto/descriptor.bin differ diff --git a/common/src/proto/komp_ac.analytics.rs b/common/src/proto/komp_ac.analytics.rs index ca207a73..482bc74b 100644 --- a/common/src/proto/komp_ac.analytics.rs +++ b/common/src/proto/komp_ac.analytics.rs @@ -252,6 +252,40 @@ pub struct ReportDashboardFilter { pub parameter: ::core::option::Option, #[prost(message, repeated, tag = "2")] pub targets: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "3")] + #[serde(default)] + pub primary: bool, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ReportDateRange { + #[prost(string, tag = "1")] + pub start_filter: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub end_filter: ::prost::alloc::string::String, + #[prost(enumeration = "ReportPeriodBoundary", tag = "3")] + pub end_boundary: i32, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ReportPeriod { + #[prost(string, tag = "1")] + pub date_basis: ::prost::alloc::string::String, + #[prost(oneof = "report_period::Selection", tags = "2, 3, 4")] + pub selection: ::core::option::Option, +} +/// Nested message and enum types in `ReportPeriod`. +pub mod report_period { + #[derive(serde::Serialize, serde::Deserialize)] + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Selection { + #[prost(message, tag = "2")] + DateRange(super::ReportDateRange), + #[prost(string, tag = "3")] + AccountingPeriodFilter(::prost::alloc::string::String), + #[prost(string, tag = "4")] + AsOfFilter(::prost::alloc::string::String), + } } #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] @@ -390,6 +424,8 @@ pub struct ReportDashboardDefinition { pub refresh_seconds: u32, #[prost(message, repeated, tag = "7")] pub dataset_versions: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "8")] + pub period: ::core::option::Option, } #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] @@ -1085,6 +1121,36 @@ impl ReportExecutionPurpose { } } } +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ReportPeriodBoundary { + Unspecified = 0, + Inclusive = 1, + Exclusive = 2, +} +impl ReportPeriodBoundary { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "REPORT_PERIOD_BOUNDARY_UNSPECIFIED", + Self::Inclusive => "REPORT_PERIOD_BOUNDARY_INCLUSIVE", + Self::Exclusive => "REPORT_PERIOD_BOUNDARY_EXCLUSIVE", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "REPORT_PERIOD_BOUNDARY_UNSPECIFIED" => Some(Self::Unspecified), + "REPORT_PERIOD_BOUNDARY_INCLUSIVE" => Some(Self::Inclusive), + "REPORT_PERIOD_BOUNDARY_EXCLUSIVE" => Some(Self::Exclusive), + _ => None, + } + } +} /// Generated client implementations. pub mod analytics_service_client { #![allow( diff --git a/common/src/reporting.rs b/common/src/reporting.rs index f3a2fb75..eca47544 100644 --- a/common/src/reporting.rs +++ b/common/src/reporting.rs @@ -263,6 +263,33 @@ fn validate_dashboard(dashboard: &ReportDashboardDefinition) -> Result<(), Strin } } } + if let Some(period) = &dashboard.period { + nonempty(&period.date_basis, "Period date basis", 160)?; + let parameter = |key: &str, kind: ReportDataType| -> Result<(), String> { + let parameter = dashboard.filters.iter().filter_map(|filter| filter.parameter.as_ref()) + .find(|parameter| parameter.key == key).ok_or("Period refers to an unknown filter")?; + let actual_kind: ReportDataType = enum_value(parameter.data_type, "period filter type")?; + if parameter.multiple || actual_kind != kind { + return Err("Period filters must have the declared single-value type".into()); + } + if !parameter.choices.is_empty() || parameter.lookup.is_some() { + return Err("Period filters use the period selector instead of custom choices".into()); + } + Ok(()) + }; + match period.selection.as_ref().ok_or("A period selection is required")? { + report_period::Selection::DateRange(range) => { + parameter(&range.start_filter, ReportDataType::Date)?; + parameter(&range.end_filter, ReportDataType::Date)?; + if range.start_filter == range.end_filter { + return Err("A period needs distinct start and end filters".into()); + } + let _: ReportPeriodBoundary = enum_value(range.end_boundary, "period end boundary")?; + } + report_period::Selection::AccountingPeriodFilter(key) => parameter(key, ReportDataType::Integer)?, + report_period::Selection::AsOfFilter(key) => parameter(key, ReportDataType::Date)?, + } + } let mut panels = HashSet::new(); for panel in &dashboard.panels { nonempty(&panel.id, "Panel ID", 64)?; diff --git a/server b/server index 27d28176..7efce3df 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 27d28176f06d3bdf67dd62d324a18303fae30279 +Subproject commit 7efce3df1842958d09b4501ebb5199b6807f127d diff --git a/tui-pages b/tui-pages index a135d67c..ce4bc49f 160000 --- a/tui-pages +++ b/tui-pages @@ -1 +1 @@ -Subproject commit a135d67c79f3f4562c994612014450ac2f0fbbfa +Subproject commit ce4bc49fa64225c8cc3ded9ce9c2e8e68cc32254 diff --git a/uniza_release.txt b/uniza_release.txt new file mode 100644 index 00000000..0aafced8 --- /dev/null +++ b/uniza_release.txt @@ -0,0 +1,13 @@ +tui-pages - MIT +MIT je licencia pomenovana po univerzite - kompatibilna s univerzitou +- kniznica pre pracu s terminalom a kniznicou ratatui(vyucovana tema) +- nadvazuje na hodiny a priamo vyucbu predmetu JR +- je v ramci existujuceho ekosystemu, ktory doplna + +Riadiaci a zaznamenavaju software - AGPL server GPL client +GPL je copyleft licencia, cize kod si nemoze firma prevziat do svojho proprietarneho systemu +- software je v podstate vysoko komplexny modularny system. +- optimalizovany na vykon, nizku latenci a vysoky objem dat +- nastavitelny, naprogramovatelny na lubovolne pouzitie +- Sluzi hlavne na vstup/vystup dat a ich analyzu +- Analyza umoznuje potencialnu optimalizaciu systemu, podvojnost, tvorbu vystupnych dokumentov, grafov apod.