Commit 91041af60b

91041af60b5a98ef01f5588478302c1ef04e043d

parent: ce71e6d93f

Unsigned

cmc <hello@cleberg.net> · 2026-07-20 19:16 UTC

fix: Generate Now tap target, remove keyboard dismiss button and launch focus

Scheduled Reports: the entire Overview section was wrapped in a single
VStack inside one List row, so SwiftUI collapsed every control into one
tap target and the menu-style Cadence Picker captured taps intended for
the Generate Now button. Unwraps the VStack so each control is its own
row, matching the pattern used in IntegrationsView and elsewhere.

Also extends the .automatedMonitoring gate to the two Pickers and the
Generate Now button. Previously only the Toggle was disabled, leaving a
button that appeared active on Free but silently no-opped against the
guard in ScheduledReportService.

Inspect tab: removes the keyboard toolbar's Dismiss Keyboard button and
the onAppear that focused the single-domain field at launch.

Layout: unified · split

DomainDig.xcodeproj/xcuserdata/cmc.xcuserdatad/xcschemes/xcschememanagement.plist +2 −2
@@ -12,12 +12,12 @@
1212 <key>DomainDigShareExtension.xcscheme_^#shared#^_</key>
1313 <dict>
1414 <key>orderHint</key>
15 <integer>2</integer>
15 <integer>1</integer>
1616 </dict>
1717 <key>DomainDigWidgetExtension.xcscheme_^#shared#^_</key>
1818 <dict>
1919 <key>orderHint</key>
20 <integer>1</integer>
20 <integer>2</integer>
2121 </dict>
2222 </dict>
2323 <key>SuppressBuildableAutocreation</key>
DomainDig/ContentView.swift −10
@@ -186,21 +186,11 @@ struct ContentView: View {
186186 }
187187 }
188188 }
189
190 ToolbarItemGroup(placement: .keyboard) {
191 Spacer()
192 Button("Dismiss Keyboard") {
193 focusedInputField = nil
194 }
195 }
196189 }
197190 .navigationDestination(for: WorkflowNavigationTarget.self) { target in
198191 WorkflowDetailView(viewModel: viewModel, workflowID: target.workflowID)
199192 }
200193 }
201 .onAppear {
202 focusedInputField = .singleDomain
203 }
204194 .task {
205195 await viewModel.refreshUsageCredits()
206196 }
DomainDig/ScheduledReportsView.swift +47 −48
@@ -10,63 +10,62 @@ struct ScheduledReportsView: View {
1010 var body: some View {
1111 List {
1212 Section("Overview") {
13 VStack(alignment: .leading, spacing: 8) {
14 if !FeatureAccessService.hasAccess(to: .automatedMonitoring) {
15 Text("Scheduled reports require Pro.")
16 .font(appDensity.font(.caption))
17 .foregroundStyle(.secondary)
18 }
13 if !FeatureAccessService.hasAccess(to: .automatedMonitoring) {
14 Text("Scheduled reports require Pro.")
15 .font(appDensity.font(.caption))
16 .foregroundStyle(.secondary)
17 }
1918
20 Toggle("Scheduled Reports", isOn: Binding(
21 get: { settings.isEnabled },
22 set: { newValue in
23 settings.isEnabled = newValue
24 saveSettings()
25 }
26 ))
27 .disabled(!FeatureAccessService.hasAccess(to: .automatedMonitoring))
19 Toggle("Scheduled Reports", isOn: Binding(
20 get: { settings.isEnabled },
21 set: { newValue in
22 settings.isEnabled = newValue
23 saveSettings()
24 }
25 ))
26 .disabled(!FeatureAccessService.hasAccess(to: .automatedMonitoring))
2827
29 Picker("Cadence", selection: Binding(
30 get: { settings.cadence },
31 set: { newValue in
32 settings.cadence = newValue
33 saveSettings()
34 }
35 )) {
36 ForEach(ScheduledReportCadence.allCases) { cadence in
37 Text(cadence.title).tag(cadence)
38 }
28 Picker("Cadence", selection: Binding(
29 get: { settings.cadence },
30 set: { newValue in
31 settings.cadence = newValue
32 saveSettings()
3933 }
34 )) {
35 ForEach(ScheduledReportCadence.allCases) { cadence in
36 Text(cadence.title).tag(cadence)
37 }
38 }
39 .disabled(!FeatureAccessService.hasAccess(to: .automatedMonitoring))
4040
41 Picker("Format", selection: Binding(
42 get: { settings.format },
43 set: { newValue in
44 settings.format = newValue
45 saveSettings()
46 }
47 )) {
48 ForEach([DomainExportFormat.markdown, .pdf, .json]) { format in
49 Text(format.title).tag(format)
50 }
41 Picker("Format", selection: Binding(
42 get: { settings.format },
43 set: { newValue in
44 settings.format = newValue
45 saveSettings()
5146 }
47 )) {
48 ForEach([DomainExportFormat.markdown, .pdf, .json]) { format in
49 Text(format.title).tag(format)
50 }
51 }
52 .disabled(!FeatureAccessService.hasAccess(to: .automatedMonitoring))
5253
53 LabeledContent(
54 "Last Generated",
55 value: settings.lastGeneratedAt?.formatted(date: .abbreviated, time: .shortened) ?? "Never"
56 )
54 LabeledContent(
55 "Last Generated",
56 value: settings.lastGeneratedAt?.formatted(date: .abbreviated, time: .shortened) ?? "Never"
57 )
5758
58 if let statusMessage {
59 Text(statusMessage)
60 .font(appDensity.font(.caption))
61 .foregroundStyle(.secondary)
62 }
59 if let statusMessage {
60 Text(statusMessage)
61 .font(appDensity.font(.caption))
62 .foregroundStyle(.secondary)
63 }
6364
64 Button(isGenerating ? "Generating…" : "Generate Now") {
65 Task { await generateNow() }
66 }
67 .disabled(isGenerating)
65 Button(isGenerating ? "Generating…" : "Generate Now") {
66 Task { await generateNow() }
6867 }
69 .padding(.vertical, 4)
68 .disabled(isGenerating || !FeatureAccessService.hasAccess(to: .automatedMonitoring))
7069 }
7170 .listRowBackground(Color(.systemGray6).opacity(0.5))
7271