diff --git a/lib/data/models/widget_model.dart b/lib/data/models/widget_model.dart index 2f389e1fa..3b9bba17d 100644 --- a/lib/data/models/widget_model.dart +++ b/lib/data/models/widget_model.dart @@ -16,7 +16,7 @@ class WidgetData { this.companies, this.companyId, this.dateRanges, - this.fields, + this.dashboardFields, }); WidgetData.fromState(AppState state, AppLocalization localization) @@ -30,7 +30,7 @@ class WidgetData { staticState: state.staticState, ) }, - fields = Map.fromIterable([ + dashboardFields = Map.fromIterable([ DashboardUISettings.FIELD_ACTIVE_INVOICES, DashboardUISettings.FIELD_OUTSTANDING_INVOICES, DashboardUISettings.FIELD_COMPLETED_PAYMENTS, @@ -47,21 +47,21 @@ class WidgetData { companyId = json['company_id'], companies = json['companies'], dateRanges = json['date_ranges'], - fields = json['fields']; + dashboardFields = json['dashboard_fields']; Map toJson() => { 'companies': companies, 'company_id': companyId, 'url': url, 'date_ranges': dateRanges, - 'fields': fields, + 'dashboard_Fields': dashboardFields, }; final String url; final String companyId; final Map companies; final Map dateRanges; - final Map fields; + final Map dashboardFields; } class WidgetCompany { diff --git a/macos/CompanyIntent/IntentHandler.swift b/macos/CompanyIntent/IntentHandler.swift index 151fb60a8..7d0ba5eb7 100644 --- a/macos/CompanyIntent/IntentHandler.swift +++ b/macos/CompanyIntent/IntentHandler.swift @@ -3,7 +3,11 @@ import Intents class IntentHandler: INExtension, ConfigurationIntentHandling { private func loadWidgetData() -> WidgetData { let sharedDefaults = UserDefaults(suiteName: "group.com.invoiceninja.app") - var widgetData: WidgetData = WidgetData(url: "", companyId: "", companies: [:], dateRanges: [:], fields: [:]) + var widgetData: WidgetData = WidgetData(url: "", + companyId: "", + companies: [:], + dateRanges: [:], + dashboardFields: [:]) if let sharedDefaults = sharedDefaults { do { @@ -71,7 +75,24 @@ class IntentHandler: INExtension, ConfigurationIntentHandling { return DateRange(identifier: defaultDateRange, display: dateRamge) } - + func provideDashboardFieldOptionsCollection(for intent: ConfigurationIntent) async throws -> INObjectCollection { + let widgetData = loadWidgetData() + + + let fields = widgetData.dashboardFields.keys.sorted().map { field in + DashboardField(identifier: field, display: widgetData.dashboardFields[field]!) + } + + return INObjectCollection(items: fields) + } + + func defaultDashboardField(for intent: ConfigurationIntent) -> DashboardField? { + let widgetData = loadWidgetData() + let defaultField = "total_active_invoices"; + let field = widgetData.dashboardFields[defaultField]!; + return DashboardField(identifier: defaultField, display: field) + } + override func handler(for intent: INIntent) -> Any { return self } diff --git a/macos/DashboardWidget/DashboardWidget.intentdefinition b/macos/DashboardWidget/DashboardWidget.intentdefinition index 99eab223c..97e6c3ad1 100644 --- a/macos/DashboardWidget/DashboardWidget.intentdefinition +++ b/macos/DashboardWidget/DashboardWidget.intentdefinition @@ -3,67 +3,13 @@ INEnums - - - INEnumDisplayName - Field - INEnumDisplayNameID - a7k58J - INEnumGeneratesHeader - - INEnumName - Field - INEnumType - Regular - INEnumValues - - - INEnumValueDisplayName - unknown - INEnumValueDisplayNameID - lwYuqc - INEnumValueName - unknown - - - INEnumValueDisplayName - Active Invoices - INEnumValueDisplayNameID - z5NmCf - INEnumValueIndex - 1 - INEnumValueName - active_invoices - - - INEnumValueDisplayName - Outstanding Invoices - INEnumValueDisplayNameID - KMErB0 - INEnumValueIndex - 2 - INEnumValueName - outstanding_invoices - - - INEnumValueDisplayName - Completed Payments - INEnumValueDisplayNameID - HEngYv - INEnumValueIndex - 3 - INEnumValueName - completed_payments - - - - + INIntentDefinitionModelVersion 1.2 INIntentDefinitionNamespace 88xZPY INIntentDefinitionSystemVersion - 21G115 + 21G651 INIntentDefinitionToolsBuildVersion 14C18 INIntentDefinitionToolsVersion @@ -80,7 +26,7 @@ INIntentIneligibleForSuggestions INIntentLastParameterTag - 11 + 12 INIntentName Configuration INIntentParameters @@ -168,17 +114,12 @@ t2MezO INIntentParameterDisplayPriority 3 - INIntentParameterEnumType - Field - INIntentParameterEnumTypeNamespace - 88xZPY - INIntentParameterMetadata - - INIntentParameterMetadataDefaultValue - active_invoices - INIntentParameterName - field + dashboardField + INIntentParameterObjectType + DashboardField + INIntentParameterObjectTypeNamespace + 88xZPY INIntentParameterPromptDialogs @@ -197,7 +138,7 @@ INIntentParameterPromptDialogCustom INIntentParameterPromptDialogFormatString - There are ${count} options matching ‘${field}’. + There are ${count} options matching ‘${dashboardField}’. INIntentParameterPromptDialogFormatStringID 3UOOUA INIntentParameterPromptDialogType @@ -207,17 +148,19 @@ INIntentParameterPromptDialogCustom INIntentParameterPromptDialogFormatString - Just to confirm, you wanted ‘${field}’? + Just to confirm, you wanted ‘${dashboardField}’? INIntentParameterPromptDialogFormatStringID 4sG08t INIntentParameterPromptDialogType Confirmation + INIntentParameterSupportsDynamicEnumeration + INIntentParameterTag - 2 + 12 INIntentParameterType - Integer + Object INIntentParameterConfigurable @@ -248,26 +191,6 @@ INIntentParameterPromptDialogType Primary - - INIntentParameterPromptDialogCustom - - INIntentParameterPromptDialogFormatString - There are ${count} options matching ‘${dateRange}’. - INIntentParameterPromptDialogFormatStringID - M1c9EE - INIntentParameterPromptDialogType - DisambiguationIntroduction - - - INIntentParameterPromptDialogCustom - - INIntentParameterPromptDialogFormatString - Just to confirm, you wanted ‘${dateRange}’? - INIntentParameterPromptDialogFormatStringID - YL2DLe - INIntentParameterPromptDialogType - Confirmation - INIntentParameterSupportsDynamicEnumeration @@ -496,6 +419,69 @@ + + INTypeDisplayName + Field + INTypeDisplayNameID + VFh9Fr + INTypeLastPropertyTag + 99 + INTypeName + DashboardField + INTypeProperties + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 1 + INTypePropertyName + identifier + INTypePropertyTag + 1 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 2 + INTypePropertyName + displayString + INTypePropertyTag + 2 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 3 + INTypePropertyName + pronunciationHint + INTypePropertyTag + 3 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 4 + INTypePropertyName + alternativeSpeakableMatches + INTypePropertySupportsMultipleValues + + INTypePropertyTag + 4 + INTypePropertyType + SpeakableString + + + diff --git a/macos/DashboardWidget/DashboardWidget.swift b/macos/DashboardWidget/DashboardWidget.swift index b369ba2c0..878c41fc0 100644 --- a/macos/DashboardWidget/DashboardWidget.swift +++ b/macos/DashboardWidget/DashboardWidget.swift @@ -65,7 +65,7 @@ struct Provider: IntentTimelineProvider { do { return try getWidgetData() } catch { - return WidgetData(url: "url", companyId: "", companies: [:], dateRanges: [:], fields: [:]) + return WidgetData(url: "url", companyId: "", companies: [:], dateRanges: [:], dashboardFields: [:]) } }() @@ -74,7 +74,6 @@ struct Provider: IntentTimelineProvider { SimpleEntry(date: Date(), configuration: ConfigurationIntent(), widgetData: widgetData, - field: "Active Invoices", value: "$100.00", error: "") } @@ -86,7 +85,6 @@ struct Provider: IntentTimelineProvider { let entry = SimpleEntry(date: Date(), configuration: configuration, widgetData: widgetData, - field: "Active Invoices", value: "$100.00", error: "") @@ -109,7 +107,7 @@ struct Provider: IntentTimelineProvider { do { widgetData = try getWidgetData() - (label, value) = try await getTimelineData(for: configuration, widgetData: widgetData!) + value = try await getTimelineData(for: configuration, widgetData: widgetData!) print("## VALUE: \(value)") @@ -123,7 +121,6 @@ struct Provider: IntentTimelineProvider { let entry = SimpleEntry(date: Date(), configuration: configuration, widgetData: widgetData, - field: label, value: value, error: message) @@ -141,11 +138,10 @@ struct Provider: IntentTimelineProvider { } } - func getTimelineData(for configuration: ConfigurationIntent, widgetData:WidgetData) async throws -> (String, String) { + func getTimelineData(for configuration: ConfigurationIntent, widgetData:WidgetData) async throws -> (String) { var rawValue = 0.0 var value = "Error" - var label = "" let companyId = configuration.company?.identifier ?? "" let company = widgetData.companies[companyId] @@ -188,22 +184,19 @@ struct Provider: IntentTimelineProvider { throw "Data not found" } - switch configuration.field { - case .active_invoices: + switch configuration.dashboardField?.identifier { + case "total_active_invoices": if let invoicedAmount = data?.invoices?.invoicedAmount, let value = Double(invoicedAmount) { rawValue = value } - label = "Active Invoices" - case .outstanding_invoices: + case "total_outstanding_invoices": if let amount = data?.outstanding?.amount, let value = Double(amount) { rawValue = value } - label = "Outstanding Invoices" - case .completed_payments: + case "total_completed_payments": if let paidToDate = data?.revenue?.paidToDate, let value = Double(paidToDate) { rawValue = value } - label = "Completed Payments" default: break } @@ -214,7 +207,7 @@ struct Provider: IntentTimelineProvider { formatter.currencyCode = currency?.code ?? "USD" value = formatter.string(from: NSNumber(value: rawValue))! - return (label, value) + return value } @@ -278,14 +271,14 @@ struct WidgetData: Decodable, Hashable { let companyId: String let companies: [String: WidgetCompany] let dateRanges: [String: String] - let fields: [String: String] + let dashboardFields: [String: String] enum CodingKeys: String, CodingKey { case url case companyId = "company_id" case companies case dateRanges = "date_ranges" - case fields + case dashboardFields = "dashboard_fields" } } @@ -327,7 +320,6 @@ struct SimpleEntry: TimelineEntry { let date: Date let configuration: ConfigurationIntent let widgetData: WidgetData? - let field: String let value: String let error: String } @@ -358,7 +350,7 @@ struct DashboardWidgetEntryView : View { HStack { VStack { - Text(entry.field) + Text(entry.configuration.dashboardField?.displayString ?? "") .font(.body) .bold() .lineLimit(2) @@ -413,7 +405,11 @@ struct DashboardWidget_Previews: PreviewProvider { do { return try getWidgetData() } catch { - return WidgetData(url: "url", companyId: "", companies: [:], dateRanges: [:], fields: [:]) + return WidgetData(url: "url", + companyId: "", + companies: [:], + dateRanges: [:], + dashboardFields: [:]) } }() @@ -421,7 +417,6 @@ struct DashboardWidget_Previews: PreviewProvider { let entry = SimpleEntry(date: Date(), configuration: ConfigurationIntent(), widgetData: widgetData, - field: "Active Invoices", value: "$100.00", error: "")