Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enterview: show full category name with delimiter #143

Merged
merged 6 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ jobs:
uses: actions/checkout@v4
- name: Clone SQLite.swift from GitHub
run: |
git clone https://github.com/stephencelis/SQLite.swift.git ../SQLite.swift
git clone --branch 0.15.3 --single-branch https://github.com/stephencelis/SQLite.swift.git ../SQLite.swift
- name: Reset SDK Cache
run: |
echo "Resetting SDK cache..."
sudo rm -rf ~/Library/Caches/com.apple.dt.Xcode/SDKs
sudo rm -rf ~/Library/Developer/Xcode/DerivedData
sudo xcrun --sdk iphoneos --show-sdk-path
echo "SDK cache reset completed."
- name: Set Default Scheme
run: |
scheme_list=$(xcodebuild -list -json | tr -d "\n")
Expand Down
7 changes: 7 additions & 0 deletions MMEX/Data/CategoryData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ struct CategoryData: ExportableEntity {
var name : String = ""
var active : Bool = false
var parentId : DataId = 0

var parentCategories: [CategoryData] = []
}

extension CategoryData {
var isRoot: Bool {
return parentId <= 0
}
func fullName(with delimiter: String = ":") -> String {
// Join all parent category names followed by the current category's name
let parentNames = parentCategories.map { $0.name }
return (parentNames + [name]).joined(separator: delimiter)
}
}

extension CategoryData: DataProtocol {
Expand Down
2 changes: 2 additions & 0 deletions MMEX/Data/InfotableData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum InfoKey: String {
case dateFormat = "DATEFORMAT"
case createDate = "CREATEDATE"
case uid = "UID"
case categDelimiter = "CATEG_DELIMITER"

var id: String { return rawValue }
}
Expand Down Expand Up @@ -57,5 +58,6 @@ extension InfotableData {
InfotableData(id: 2, name: InfoKey.createDate.id, value: DateString(Date()).string),
InfotableData(id: 3, name: InfoKey.baseCurrencyID.id, value: "1"),
InfotableData(id: 4, name: InfoKey.defaultAccountID.id, value: "1"),
InfotableData(id: 5, name: InfoKey.categDelimiter.id, value: ":"),
]
}
15 changes: 3 additions & 12 deletions MMEX/View/Enter/EnterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ struct EnterView: View {
@Environment(\.dismiss) var dismiss

@State private var accountId: [DataId] = []
@State private var categories: [CategoryData] = []
@State private var payees: [PayeeData] = []

var body: some View {
NavigationStack {
TransactionEditView(
viewModel: viewModel,
accountId: $accountId,
categories: $categories,
categories: $viewModel.categories,
payees: $payees,
txn: $newTxn
)
Expand All @@ -51,7 +51,7 @@ struct EnterView: View {
// .navigationBarTitle("Add Transaction", displayMode: .inline)
.onAppear() {
loadAccounts()
loadCategories()
viewModel.loadCategories()
loadPayees()
// TODO update initial payee (e.g. last used)
// TODO update category, payee associated?
Expand Down Expand Up @@ -85,13 +85,4 @@ struct EnterView: View {
}
}
}

func loadCategories() {
DispatchQueue.global(qos: .background).async {
let loadedCategories = env.categoryRepository?.load() ?? []
DispatchQueue.main.async {
self.categories = loadedCategories
}
}
}
}
5 changes: 5 additions & 0 deletions MMEX/View/Settings/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ struct SettingsView: View {
Spacer()
Text("\(dateFormat)")
}
HStack {
Text("Category Delimiter")
Spacer()
Text("\(viewModel.categDelimiter)")
}
Picker("Base Currency", selection: $viewModel.baseCurrencyId) {
ForEach(viewModel.currencies) { currency in
HStack {
Expand Down
2 changes: 2 additions & 0 deletions MMEX/View/Transaction/TransactionAddView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import SwiftUI

struct TransactionAddView: View {
@ObservedObject var viewModel: TransactionViewModel
@Binding var accountId: [DataId]
@Binding var categories: [CategoryData]
@Binding var payees: [PayeeData]
Expand All @@ -19,6 +20,7 @@ struct TransactionAddView: View {
var body: some View {
NavigationStack {
TransactionEditView(
viewModel: viewModel,
accountId: $accountId,
categories: $categories,
payees: $payees,
Expand Down
1 change: 1 addition & 0 deletions MMEX/View/Transaction/TransactionDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ struct TransactionDetailView: View {
.sheet(isPresented: $isPresentingEditView) {
NavigationStack {
TransactionEditView(
viewModel: viewModel,
accountId: $accountId,
categories: $categories,
payees: $payees,
Expand Down
5 changes: 4 additions & 1 deletion MMEX/View/Transaction/TransactionEditView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import SwiftUI

struct TransactionEditView: View {
@EnvironmentObject var env: EnvironmentManager // Access EnvironmentManager
@ObservedObject var viewModel: TransactionViewModel
@Binding var accountId: [DataId] // sorted by name
@Binding var categories: [CategoryData]
@Binding var payees: [PayeeData]
Expand Down Expand Up @@ -143,7 +144,7 @@ struct TransactionEditView: View {
Text("Category").tag(0 as Int64) // not set
}
ForEach(categories) { category in
Text(category.name).tag(category.id)
Text(category.fullName(with: viewModel.categDelimiter)).tag(category.id)
}
}
.pickerStyle(MenuPickerStyle()) // Show a menu for the category picker
Expand Down Expand Up @@ -277,6 +278,7 @@ struct TransactionEditView: View {

#Preview("txn 0") {
TransactionEditView(
viewModel: TransactionViewModel(env: EnvironmentManager.sampleData),
accountId: .constant(AccountData.sampleDataIds),
categories: .constant(CategoryData.sampleData),
payees: .constant(PayeeData.sampleData),
Expand All @@ -287,6 +289,7 @@ struct TransactionEditView: View {

#Preview("txn 3") {
TransactionEditView(
viewModel: TransactionViewModel(env: EnvironmentManager.sampleData),
accountId: .constant(AccountData.sampleDataIds),
categories: .constant(CategoryData.sampleData),
payees: .constant(PayeeData.sampleData),
Expand Down
1 change: 1 addition & 0 deletions MMEX/View/Transaction/TransactionListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct TransactionListView: View {
}
.sheet(isPresented: $isPresentingTransactionAddView) {
TransactionAddView(
viewModel: viewModel,
accountId: $viewModel.accountId,
categories: $viewModel.categories,
payees: $viewModel.payees,
Expand Down
35 changes: 33 additions & 2 deletions MMEX/ViewModel/TransactionViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class TransactionViewModel: ObservableObject {
@Published var defaultAccountId: DataId = 0
@Published var baseCurrency: CurrencyData?
@Published var defaultAccount: AccountData?
@Published var categDelimiter: String = ":"

private var cancellables = Set<AnyCancellable>()

Expand Down Expand Up @@ -71,6 +72,10 @@ class TransactionViewModel: ObservableObject {
from: AccountRepository.table.filter(AccountRepository.col_id == Int64(defaultAccountId))
).toOptional()
}

if let categDelimiter = infotableRepo?.getValue(for: InfoKey.categDelimiter.id, as: String.self) {
self.categDelimiter = categDelimiter
}
}

// Set up individual bindings for each @Published property
Expand Down Expand Up @@ -120,13 +125,39 @@ class TransactionViewModel: ObservableObject {
}
}

private func populateParentCategories(for categories: [CategoryData]) -> [CategoryData] {
// Create a dictionary for quick parent lookups
let categoryDict = Dictionary(uniqueKeysWithValues: categories.map { ($0.id, $0) })

return categories.map { category in
var updatedCategory = category
updatedCategory.parentCategories = self.findParentCategories(for: category, in: categoryDict)
return updatedCategory
}
}

private func findParentCategories(for category: CategoryData, in categoryDict: [DataId: CategoryData]) -> [CategoryData] {
// Recursive function to find all parent categories
var parents: [CategoryData] = []

var currentCategory = category
while let parentCategory = categoryDict[currentCategory.parentId], parentCategory.id != 0 {
parents.insert(parentCategory, at: 0) // Insert at the beginning to maintain the correct order
currentCategory = parentCategory
}

return parents
}

func loadCategories() {
let repository = env.categoryRepository
DispatchQueue.global(qos: .background).async {
let loadedCategories = repository?.load() ?? []
let loadedCategoryDict = Dictionary(uniqueKeysWithValues: loadedCategories.map { ($0.id, $0) })
let updatedCategories = self.populateParentCategories(for: loadedCategories)

let loadedCategoryDict = Dictionary(uniqueKeysWithValues: updatedCategories.map { ($0.id, $0) })
DispatchQueue.main.async {
self.categories = loadedCategories
self.categories = updatedCategories
self.categoryDict = loadedCategoryDict
}
}
Expand Down
Loading