iOS: Diagramm-Einstellungen im lokalen App-Editor
Der lokale Uebersicht-Editor kann jetzt pro Diagramm-Karte einstellen, wie im Web-Editor: - Ablauf-Ring: 'Ohne MHD einbeziehen' - Kategorien-Ring: 'Detailansicht' (alle einzeln) + 'Kategorie-Tiefe' AppCard speichert die Optionen (optional -> alte Uebersichten dekodieren weiter) und reicht sie an DashboardCardView durch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -16,11 +16,21 @@ struct AppCard: Codable, Identifiable, Equatable {
|
|||||||
let id: UUID
|
let id: UUID
|
||||||
var type: String
|
var type: String
|
||||||
var productId: Int?
|
var productId: Int?
|
||||||
|
// Diagramm-Einstellungen (nur fuer bestimmte Diagramme relevant). Optional,
|
||||||
|
// damit aeltere gespeicherte Uebersichten ohne diese Schluessel weiter
|
||||||
|
// dekodieren. Bedeutung wie im Web-Editor:
|
||||||
|
var mitOhneMhd: Bool? // Ablauf-Ring: „Ohne MHD" einbeziehen (nil = ja)
|
||||||
|
var detail: Bool? // Kategorien-Ring: Detailansicht, alle einzeln (nil = nein)
|
||||||
|
var tiefe: Int? // Kategorien-Ring: Tiefe (nil = feinste Ebene)
|
||||||
|
|
||||||
init(id: UUID = UUID(), type: String, productId: Int? = nil) {
|
init(id: UUID = UUID(), type: String, productId: Int? = nil,
|
||||||
|
mitOhneMhd: Bool? = nil, detail: Bool? = nil, tiefe: Int? = nil) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.type = type
|
self.type = type
|
||||||
self.productId = productId
|
self.productId = productId
|
||||||
|
self.mitOhneMhd = mitOhneMhd
|
||||||
|
self.detail = detail
|
||||||
|
self.tiefe = tiefe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ struct LocalOverview: View {
|
|||||||
ForEach(aktives.cards) { karte in
|
ForEach(aktives.cards) { karte in
|
||||||
Section {
|
Section {
|
||||||
DashboardCardView(type: karte.type, productId: karte.productId,
|
DashboardCardView(type: karte.type, productId: karte.productId,
|
||||||
stand: stand) { stand += 1 }
|
stand: stand,
|
||||||
|
detail: karte.detail ?? false,
|
||||||
|
tiefe: karte.tiefe,
|
||||||
|
mitOhneMhd: karte.mitOhneMhd ?? true) { stand += 1 }
|
||||||
} header: {
|
} header: {
|
||||||
Text(titel(karte))
|
Text(titel(karte))
|
||||||
}
|
}
|
||||||
@@ -82,14 +85,12 @@ struct LocalOverview: View {
|
|||||||
}
|
}
|
||||||
Section {
|
Section {
|
||||||
ForEach(aktives?.cards ?? []) { karte in
|
ForEach(aktives?.cards ?? []) { karte in
|
||||||
HStack {
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
|
||||||
Text(CardCatalog.titel(karte.type))
|
Text(CardCatalog.titel(karte.type))
|
||||||
if CardCatalogList.kind(for: karte.type)?.needsProduct == true {
|
if CardCatalogList.kind(for: karte.type)?.needsProduct == true {
|
||||||
artikelWahl(fuer: karte)
|
artikelWahl(fuer: karte)
|
||||||
}
|
}
|
||||||
}
|
diagrammEinstellungen(fuer: karte)
|
||||||
Spacer()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onDelete(perform: loesche)
|
.onDelete(perform: loesche)
|
||||||
@@ -158,6 +159,53 @@ struct LocalOverview: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Diagramm-Einstellungen (nur bestimmte Ringe, wie im Web-Editor)
|
||||||
|
|
||||||
|
private struct TiefeOption: Identifiable {
|
||||||
|
let tiefe: Int?
|
||||||
|
let label: String
|
||||||
|
var id: String { label }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static let tiefeOptionen: [TiefeOption] = [
|
||||||
|
.init(tiefe: nil, label: "Feinste (jede Kategorie einzeln)"),
|
||||||
|
.init(tiefe: 1, label: "Nur oberste Stufe"),
|
||||||
|
.init(tiefe: 2, label: "Bis 2. Stufe"),
|
||||||
|
.init(tiefe: 3, label: "Bis 3. Stufe"),
|
||||||
|
]
|
||||||
|
|
||||||
|
@ViewBuilder private func diagrammEinstellungen(fuer karte: AppCard) -> some View {
|
||||||
|
switch karte.type {
|
||||||
|
case "expiry-donut":
|
||||||
|
Toggle(isOn: Binding(
|
||||||
|
get: { karte.mitOhneMhd ?? true },
|
||||||
|
set: { setzeMitOhneMhd(karte, $0) }
|
||||||
|
)) {
|
||||||
|
Text("„Ohne MHD“ einbeziehen").font(.caption)
|
||||||
|
}
|
||||||
|
case "category-donut":
|
||||||
|
Toggle(isOn: Binding(
|
||||||
|
get: { karte.detail ?? false },
|
||||||
|
set: { setzeDetail(karte, $0) }
|
||||||
|
)) {
|
||||||
|
Text("Detailansicht (alle einzeln)").font(.caption)
|
||||||
|
}
|
||||||
|
Menu {
|
||||||
|
ForEach(Self.tiefeOptionen) { opt in
|
||||||
|
Button(opt.label) { setzeTiefe(karte, opt.tiefe) }
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
HStack(spacing: 4) {
|
||||||
|
Text("Tiefe:").font(.caption).foregroundStyle(.secondary)
|
||||||
|
Text(Self.tiefeOptionen.first { $0.tiefe == karte.tiefe }?.label ?? "Feinste")
|
||||||
|
.font(.caption).foregroundStyle(Color.marke)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
EmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Datenänderungen (alle sofort gespeichert)
|
// MARK: - Datenänderungen (alle sofort gespeichert)
|
||||||
|
|
||||||
private func mutiere(_ block: (inout AppDashboard) -> Void) {
|
private func mutiere(_ block: (inout AppDashboard) -> Void) {
|
||||||
@@ -169,15 +217,32 @@ struct LocalOverview: View {
|
|||||||
|
|
||||||
private func fuegeHinzu(_ karte: AppCard) { mutiere { $0.cards.append(karte) } }
|
private func fuegeHinzu(_ karte: AppCard) { mutiere { $0.cards.append(karte) } }
|
||||||
|
|
||||||
private func setzeProdukt(_ karte: AppCard, _ pid: Int?) {
|
/// Ändert genau eine Karte und lädt die Anzeige neu.
|
||||||
|
private func mutiereKarte(_ karte: AppCard, _ block: (inout AppCard) -> Void) {
|
||||||
mutiere { dash in
|
mutiere { dash in
|
||||||
if let i = dash.cards.firstIndex(where: { $0.id == karte.id }) {
|
if let i = dash.cards.firstIndex(where: { $0.id == karte.id }) {
|
||||||
dash.cards[i].productId = pid
|
block(&dash.cards[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stand += 1
|
stand += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func setzeProdukt(_ karte: AppCard, _ pid: Int?) {
|
||||||
|
mutiereKarte(karte) { $0.productId = pid }
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setzeMitOhneMhd(_ karte: AppCard, _ wert: Bool) {
|
||||||
|
mutiereKarte(karte) { $0.mitOhneMhd = wert }
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setzeDetail(_ karte: AppCard, _ wert: Bool) {
|
||||||
|
mutiereKarte(karte) { $0.detail = wert }
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setzeTiefe(_ karte: AppCard, _ wert: Int?) {
|
||||||
|
mutiereKarte(karte) { $0.tiefe = wert }
|
||||||
|
}
|
||||||
|
|
||||||
private func loesche(at offsets: IndexSet) { mutiere { $0.cards.remove(atOffsets: offsets) } }
|
private func loesche(at offsets: IndexSet) { mutiere { $0.cards.remove(atOffsets: offsets) } }
|
||||||
private func verschiebe(from: IndexSet, to: Int) { mutiere { $0.cards.move(fromOffsets: from, toOffset: to) } }
|
private func verschiebe(from: IndexSet, to: Int) { mutiere { $0.cards.move(fromOffsets: from, toOffset: to) } }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user