Jul 30 - Update iPad - inspector can re-inspect and create follow-up
This commit is contained in:
@@ -42,6 +42,19 @@ struct DashboardView: View {
|
||||
order: .reverse
|
||||
) private var myInspections: [LocalInspection]
|
||||
|
||||
/// Outstanding follow-up requests, counted into the My Inspections badge so
|
||||
/// the inspector sees there is work waiting from any tab — the same reason
|
||||
/// in-progress inspections are counted there.
|
||||
@Query private var followUpRequests: [LocalFollowUpRequest]
|
||||
|
||||
/// Badge count for My Inspections: in-progress work plus outstanding
|
||||
/// follow-ups. `fulfilledLocally` rows are excluded in Swift, not in the
|
||||
/// @Query predicate (CLAUDE.md rule 3), so the badge drops the instant a
|
||||
/// re-inspection is submitted.
|
||||
private var myInspectionsBadgeCount: Int {
|
||||
myInspections.count + followUpRequests.filter { !$0.fulfilledLocally }.count
|
||||
}
|
||||
|
||||
@State private var selectedTab: SidebarTab = .dashboard
|
||||
/// Each sidebar tap refreshes the UUID for that tab, forcing its
|
||||
/// NavigationStack to be destroyed and recreated — even when the tab
|
||||
@@ -181,8 +194,8 @@ struct DashboardView: View {
|
||||
Label("My Inspections", systemImage: "checklist")
|
||||
.foregroundStyle(tint)
|
||||
Spacer()
|
||||
if !myInspections.isEmpty {
|
||||
Text("\(myInspections.count)")
|
||||
if myInspectionsBadgeCount > 0 {
|
||||
Text("\(myInspectionsBadgeCount)")
|
||||
.font(.caption2)
|
||||
.padding(.horizontal, 6).padding(.vertical, 2)
|
||||
.background(Color.blue.opacity(0.15))
|
||||
@@ -332,6 +345,10 @@ struct DashboardStatsView: View {
|
||||
/// inspection empties its @Query while the start form is still presented.
|
||||
@State private var scheduledStartTarget: ScheduledStartTarget? = nil
|
||||
|
||||
/// The follow-up request tapped in FollowUpRequestsCard. Held here for the
|
||||
/// same reason as `scheduledStartTarget` — see the covers at the bottom.
|
||||
@State private var followUpStartTarget: FollowUpStartTarget? = nil
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(alignment: .leading, spacing: 20) {
|
||||
@@ -341,6 +358,15 @@ struct DashboardStatsView: View {
|
||||
DraftResumeBanner(drafts: draftInspections, context: context)
|
||||
}
|
||||
|
||||
// ── Follow-up Requests ─────────────────────────────────────
|
||||
// Re-inspections a director asked for. Ranked above SCHEDULED:
|
||||
// a follow-up is remedial work on a facility that already failed
|
||||
// once, so it is the more urgent of the two. Self-hides when
|
||||
// there are none. Tap a row to start the linked re-inspection.
|
||||
FollowUpRequestsCard(onStart: { target in
|
||||
followUpStartTarget = target
|
||||
})
|
||||
|
||||
// ── Scheduled Inspections (phase36) ────────────────────────
|
||||
// Planned/recurring assignments for this inspector. Self-hides
|
||||
// when there are none. Tap a row to start it (facility +
|
||||
@@ -484,10 +510,34 @@ struct DashboardStatsView: View {
|
||||
StartInspectionView(
|
||||
preFillTemplateId: t.templateServerId,
|
||||
preFillFacilityId: t.facilityServerId,
|
||||
// phase45 — nil for an ordinary schedule; set when this row is a
|
||||
// planned follow-up, which makes the run a linked re-inspection.
|
||||
// Must precede preFillScheduleId: argument order follows the
|
||||
// property declaration order in StartInspectionView.
|
||||
parentServerId: t.parentServerId,
|
||||
preFillScheduleId: t.id,
|
||||
preFillScheduleInstructions: t.instructions
|
||||
)
|
||||
}
|
||||
// Start cover for a tapped follow-up request. Owned here for the same
|
||||
// reason as the scheduled cover above: FollowUpRequestsCard self-hides
|
||||
// the instant its last row is invalidated at submit, which is exactly
|
||||
// when this cover is on screen.
|
||||
//
|
||||
// `parentServerId` is what makes this a re-inspection rather than a
|
||||
// fresh one — the server reads it to clear follow_up_required on the
|
||||
// flagged inspection. `parentLocalId` stays nil: the parent synced long
|
||||
// ago (that is how it got flagged), so serverId is the reliable handle,
|
||||
// and clearParentFollowUpFlag()'s fallback-1 matches on it.
|
||||
.fullScreenCover(item: $followUpStartTarget) { t in
|
||||
StartInspectionView(
|
||||
preFillTemplateId: t.templateServerId,
|
||||
preFillFacilityId: t.facilityServerId,
|
||||
parentServerId: t.id,
|
||||
preFillFollowUpNote: t.note,
|
||||
preFillParentFormDataJSON: t.parentFormDataJSON
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user