Compare commits
No commits in common. "app/add-repository" and "main" have entirely different histories.
app/add-re
...
main
@ -42,57 +42,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings.button.add-repository.text" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Add repository"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings.column.active.text" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Active"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings.column.folder.text" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Folder"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings.column.name.text" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Name"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings.item.active.text" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : " "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings.tab-bar.repositories.text" : {
|
"settings.tab-bar.repositories.text" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
|
@ -17,32 +17,22 @@ final class Repository {
|
|||||||
@Attribute(.unique) var path: URL
|
@Attribute(.unique) var path: URL
|
||||||
|
|
||||||
var addedAt: Date
|
var addedAt: Date
|
||||||
var active: Bool
|
var sortOrder: Int
|
||||||
|
|
||||||
// MARK: Initialisers
|
// MARK: Initialisers
|
||||||
|
|
||||||
init(
|
init(
|
||||||
_ path: URL,
|
_ path: URL,
|
||||||
active: Bool = true,
|
sortOrder: Int,
|
||||||
addedAt: Date = .now
|
addedAt: Date = .now
|
||||||
) {
|
) {
|
||||||
self.path = path
|
self.path = path
|
||||||
self.addedAt = addedAt
|
self.addedAt = addedAt
|
||||||
self.active = active
|
self.sortOrder = sortOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Computed
|
// MARK: Computed
|
||||||
|
|
||||||
@Transient var folder: String {
|
@Transient var name: String { path.lastPathComponent }
|
||||||
path.deletingLastPathComponent().relativePath
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transient var name: String {
|
|
||||||
path.lastPathComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Identifiable
|
|
||||||
|
|
||||||
extension Repository: Identifiable {}
|
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
//
|
|
||||||
// RepositoriesViewModel.swift
|
|
||||||
// Piper ~ App
|
|
||||||
//
|
|
||||||
// Created by Javier Cicchelli on 21/10/2024.
|
|
||||||
// Copyright © 2024 Röck+Cöde. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Observation
|
|
||||||
import SwiftData
|
|
||||||
|
|
||||||
@Observable
|
|
||||||
final class RepositoriesViewModel {
|
|
||||||
|
|
||||||
// MARK: Properties
|
|
||||||
|
|
||||||
var fileImporterOpened: Bool = false
|
|
||||||
var rowsSelected: Set<Repository.ID> = []
|
|
||||||
|
|
||||||
// MARK: Functions
|
|
||||||
|
|
||||||
func addRepository(
|
|
||||||
_ result: Result<URL, any Error>,
|
|
||||||
into context: ModelContext
|
|
||||||
) {
|
|
||||||
do {
|
|
||||||
let url = try result.get()
|
|
||||||
let repository = Repository(url)
|
|
||||||
|
|
||||||
context.insert(repository)
|
|
||||||
} catch {
|
|
||||||
// TODO: Handle this error gracefully.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -18,16 +18,18 @@ extension Repository {
|
|||||||
let context = container.mainContext
|
let context = container.mainContext
|
||||||
|
|
||||||
context.insert(Repository(
|
context.insert(Repository(
|
||||||
URL(filePath: "/full/path/to/repository/name-0.git")
|
URL(filePath: "/full/path/to/repository/name-0.git"),
|
||||||
|
sortOrder: 0
|
||||||
))
|
))
|
||||||
|
|
||||||
context.insert(Repository(
|
context.insert(Repository(
|
||||||
URL(filePath: "/full/path/to/repository/name-1.git"),
|
URL(filePath: "/full/path/to/repository/name-1.git"),
|
||||||
active: false
|
sortOrder: 1
|
||||||
))
|
))
|
||||||
|
|
||||||
context.insert(Repository(
|
context.insert(Repository(
|
||||||
URL(filePath: "/full/path/to/repository/name-2.git")
|
URL(filePath: "/full/path/to/repository/name-2.git"),
|
||||||
|
sortOrder: 2
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,15 +62,24 @@ struct ItemLabelStyle: LabelStyle {
|
|||||||
|
|
||||||
#Preview("List Item component") {
|
#Preview("List Item component") {
|
||||||
List {
|
List {
|
||||||
ListItem(repository: .init(
|
ListItem(
|
||||||
.init(filePath: "/full/path/to/repository/name.git")!
|
repository: .init(
|
||||||
))
|
.init(filePath: "/full/path/to/repository/name.git")!,
|
||||||
ListItem(repository: .init(
|
sortOrder: 0
|
||||||
.init(filePath: "/full/path/to/repository/name.git")!
|
)
|
||||||
))
|
)
|
||||||
ListItem(repository: .init(
|
ListItem(
|
||||||
.init(filePath: "/full/path/to/repository/name.git")!
|
repository: .init(
|
||||||
))
|
.init(filePath: "/full/path/to/repository/name.git")!,
|
||||||
|
sortOrder: 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ListItem(
|
||||||
|
repository: .init(
|
||||||
|
.init(filePath: "/full/path/to/repository/name.git")!,
|
||||||
|
sortOrder: 0
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.frame(width: 400, height: 220)
|
.frame(width: 400, height: 220)
|
||||||
}
|
}
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
//
|
|
||||||
// RepositoriesView.swift
|
|
||||||
// Piper ~ App
|
|
||||||
//
|
|
||||||
// Created by Javier Cicchelli on 14/10/2024.
|
|
||||||
// Copyright © 2024 Röck+Cöde. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftData
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct RepositoriesView: View {
|
|
||||||
|
|
||||||
// MARK: Properties
|
|
||||||
|
|
||||||
@Environment(\.modelContext) private var modelContext
|
|
||||||
|
|
||||||
@Query(sort: \Repository.addedAt)
|
|
||||||
private var repositories: [Repository]
|
|
||||||
|
|
||||||
@State private var viewModel: RepositoriesViewModel = .init()
|
|
||||||
|
|
||||||
// MARK: Body
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
HStack(
|
|
||||||
alignment: .top,
|
|
||||||
spacing: Layout.spacingHorizontal
|
|
||||||
) {
|
|
||||||
Table(
|
|
||||||
repositories,
|
|
||||||
selection: $viewModel.rowsSelected
|
|
||||||
) {
|
|
||||||
TableColumn("settings.column.active.text") { repository in
|
|
||||||
HStack {
|
|
||||||
Toggle("settings.item.active.text", isOn: .init {
|
|
||||||
repository.active
|
|
||||||
} set: {
|
|
||||||
repository.active = $0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TableColumn("settings.column.name.text") { repository in
|
|
||||||
Text(repository.name)
|
|
||||||
.fontWeight(.semibold)
|
|
||||||
.foregroundStyle(.primary)
|
|
||||||
}
|
|
||||||
|
|
||||||
TableColumn("settings.column.folder.text") { repository in
|
|
||||||
Text(repository.folder)
|
|
||||||
.fontWeight(.regular)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VStack {
|
|
||||||
Button("settings.button.add-repository.text") {
|
|
||||||
viewModel.fileImporterOpened = true
|
|
||||||
}
|
|
||||||
.fileImporter(
|
|
||||||
isPresented: $viewModel.fileImporterOpened,
|
|
||||||
allowedContentTypes: [.pdf]
|
|
||||||
) {
|
|
||||||
viewModel.addRepository($0, into: modelContext)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Layout
|
|
||||||
|
|
||||||
private extension RepositoriesView {
|
|
||||||
enum Layout {
|
|
||||||
static let spacingHorizontal = CGFloat(16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Previews
|
|
||||||
|
|
||||||
@available(macOS 15.0, *)
|
|
||||||
#Preview(
|
|
||||||
"Repositories view when no repositories found (macOS 15)",
|
|
||||||
traits: .emptyData
|
|
||||||
) {
|
|
||||||
RepositoriesView()
|
|
||||||
.scenePadding()
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS, obsoleted: 15)
|
|
||||||
#Preview("Repositories view when no repositories found (macOS 14)") {
|
|
||||||
MenuBarView()
|
|
||||||
.modelContainer(.preview)
|
|
||||||
.scenePadding()
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 15.0, *)
|
|
||||||
#Preview(
|
|
||||||
"Repositories view when repositories found (macOS 15)",
|
|
||||||
traits: .sampleData
|
|
||||||
) {
|
|
||||||
RepositoriesView()
|
|
||||||
.scenePadding()
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS, obsoleted: 15)
|
|
||||||
#Preview("Repositories view when repositories found (macOS 14)") {
|
|
||||||
let container = ModelContainer.preview
|
|
||||||
|
|
||||||
Repository.samples(in: container)
|
|
||||||
|
|
||||||
return RepositoriesView()
|
|
||||||
.modelContainer(container)
|
|
||||||
.scenePadding()
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user