Drilldown sections: State Banner & अपडेट

Reference for what these two sections do, and every state they can render — Install + Service Ticket (Restore) drilldowns.

The two sections at a glance

Every task drilldown opens with the same two cards at the top. They look similar but answer different questions.

1. State Banner

"What's happening RIGHT NOW with this task?"
  • Always shown — exactly one banner, picked by a state machine.
  • Title + subtitle + circular icon in a coloured tint.
  • 4 colour families: warning, info, positive, negative.
  • Snapshot of the current state — never empty.

2. अपडेट (Updates)

"What has happened so far, in order?"
  • Historical timeline — DESC (newest first).
  • Paginated 5 at a time via "और देखें".
  • Unseen entries highlighted with brand-tint background.
  • Empty state shows "अभी कोई अपडेट नहीं".
Mental model: Banner = where we are. अपडेट = how we got here.

Install drilldown — every banner state

Mapped in InstallStateBanner.kt → bannerVariantFor().

#StateSeverityTitle (Hindi)
1AWAITING_SLOT_PROPOSALwarningसमय चुनना बाकी है
2AWAITING_CUSTOMER_SELECTIONinfoइंस्टॉलेशन का समय कन्फर्म हो रहा है
3AWAITING_CUSTOMER_SLOT_CONFIRMATIONinfoकनेक्शन के कन्फ़र्मेशन का इंतज़ार
4AWAITING_TECHNICIAN_ASSIGNMENTwarningटेक्निशियन चुनना बाकी है
5TECHNICIAN_ASSIGNEDpositiveटेक्निशियन तय हो गया
6SLOT_CONFIRMEDpositiveस्लॉट पक्का हुआ
7SCHEDULED (future day)positiveइंस्टॉलेशन पक्का हुआ
8SCHEDULED (slot day = today)warningआज इंस्टॉलेशन का दिन है
9ARRIVED_AT_SITEpositiveटीम पहुँच गया
10NEEDS_RESCHEDULINGwarningकनेक्शन के लिए नया समय चुनें
11SCHEDULING_FAILEDinfoकनेक्शन ने स्लॉट कन्फर्म नहीं किया
12IN_PROGRESS + pre-fee / fee-pending / post-fee / awaiting-OTPinfoइंस्टॉलेशन पर काम चल रहा है
13INSTALL_SUBMITTEDinfoइंस्टॉलेशन पूरा हुआ — वेरिफाई के लिए तैयार
14DELEGATED_NOT_STARTEDinfo{name} ने इंस्टॉलेशन अभी शुरू नहीं किया
15DELEGATED_IN_PROGRESSinfo{name} काम कर रहे हैं
16DELEGATED_OVERDUEnegative{name} ने कनेक्शन इंस्टॉलेशन में देरी कर दी
17VERIFICATION_PENDINGinfoइंस्टॉलेशन वेरिफाई हो रहा है
18RESOLVEDpositiveइंस्टॉलेशन पूरा हुआ — {amount} मिले
19INSTALLATION_REPORTED_FAILEDnegativeइंस्टॉलेशन असफल रिपोर्ट किया गया
Special branches: SCHEDULED splits on task.isSlotDay (today vs future). RESOLVED swaps to amount-template when commissionDisplay is non-empty. All DELEGATED_* states interpolate the executor's name into the title.

Service Ticket (Restore) drilldown — every banner state

Mapped in RestoreDrilldownContent.kt → RestoreStateBanner().

#StateSeverityTitle (Hindi)
1PENDING_ACCEPTANCE / RESPOND_NOWwarningतुरंत ध्यान दें
2ACCEPTEDinfoकाम शुरू करें
3WORKINGinfoकाम जारी है
4ASSIGNED_TECHNICIANinfoटीम मेम्बर असाइन हुआ
5DELEGATED_NOT_STARTEDinfoटीम मेम्बर को भेजा — शुरू नहीं हुआ
6DELEGATED_IN_PROGRESSinfoटीम मेम्बर काम कर रहा है
7DELEGATED_OVERDUEnegativeसमय निकल गया
8ESCALATED_CSP_ACTIVEnegativeएस्केलेट हुआ — आपकी कार्रवाई ज़रूरी
9ESCALATED_PLATFORM_TAKEOVERnegativeWiom ने ले लिया है
10CUSTOMER_DENIEDnegativeग्राहक ने मना किया
11VERIFICATION_PENDINGinfoजाँच हो रही है
12RESOLVEDpositiveसमस्या ठीक हो गई
13RECLASSIFIEDinfoदोबारा वर्गीकृत हुआ
Body simplification: the restore drilldown's proof flow is hidden in VERIFICATION_PENDING, RESOLVED, RECLASSIFIED, and ESCALATED_PLATFORM_TAKEOVER — the banner stays but the body collapses to a summary.

अपडेट section — deep dive

Purpose

The अपडेट section is the chronological event log for a task. While the banner answers "where are we now?", अपडेट answers "how did we get here?". Every state morph, slot proposal, technician assignment, or system action that happens to this task gets appended as a row.

Visual anatomy

📈 अपडेट 2
कनेक्शन को 2 समय भेजे 10 Apr, 10:14 AM
नई कनेक्शन रिक्वेस्ट मिली 10 Apr, 9:58 AM
CSP को दिया गया 9 Apr, 9:01 AM
नई कनेक्शन रिक्वेस्ट मिली 9 Apr, 9:00 AM
और देखें (5 और)

Data model

data class TimelineEventInfo(
    val timestamp: String,        // pre-formatted by BE, e.g. "10 Apr, 10:14 AM"
    val description: String,      // Hindi copy from BE
    val timestampEn: String = "",
    val descriptionEn: String = "", // English copy from BE
)

// On TaskDetail:
val timeline: List<TimelineEventInfo> = emptyList()  // current visible page(s)
val timelineTotalElements: Int = 0                    // total on server
val timelineLoadedPage: Int = -1                      // highest page idx loaded

Backend returns the timeline ordered DESC (newest first). The client never re-sorts — it just appends incoming pages to the end.

Pagination — how "और देखें" works

StepWhat happens
1. Drilldown opensHomeViewModel.fetchInstallTimeline() hits GET /install/candidates/{id}/timeline?page=0&size=5
2. Server replies5 newest entries + totalElements (e.g. 15) + page index 0
3. Link computationremaining = totalElements − visible. If remaining > 0, render link with min(remaining, 5) as the displayed count.
4. User tapsloadMoreInstallTimeline(taskId) increments timelineLoadedPage, fetches next page, appends results.
5. All loadedWhen timeline.size ≥ timelineTotalElements, the link disappears. Call is idempotent — guard line at HomeViewModel.kt:1534.

Link copy: "और देखें ({count} और)" / "See more ({count} more)". The displayed count always advertises the next page size (5) so the copy doesn't decrement on every tap (15→10→5 would feel like progress is slowing down). The final tap may load fewer than 5 if the total isn't a multiple of the page size — that smaller count is shown then.

Unseen handling — the pink-tint rule

Each task carries unseenCount on its drilldown payload (latest_attention_version − acked_attention_version on the backend).

States that trigger a new timeline entry (Install)

TriggerSample description (hi)
Task created on CSPनई कनेक्शन रिक्वेस्ट मिली
Assigned to CSPCSP को दिया गया
Slots proposedकनेक्शन को 2 समय भेजे
Customer picked slotइंस्टॉलेशन के लिए दोपहर, 11 am – 1 pm, सोमवार 14 अप्रैल चुना गया है
Slot auto-confirmedस्लॉट ऑटो-कन्फर्म हुआ
Technician assigned{name} को असाइन किया
Arrived at siteटीम साइट पर पहुँची
Installation submittedइंस्टॉलेशन सबमिट हुआ
Verification startedव्योम जाँच कर रहा है
Resolvedइंस्टॉलेशन पूरा हुआ
Reschedule requestedनए स्लॉट भेजे

Behaviour-rules summary

TriggerWhat renders
task.timeline.isEmpty()"अभी कोई अपडेट नहीं" hint in textHint color; section visible but body is just the hint line.
task.unseenCount > 0Section auto-expands; pink badge with count next to the title; top-N rows highlighted with bgBrandTint.
unseenCount == 0 & has entriesSection collapsed by default; tap header to expand. All rows in textSecondary.
timelineTotalElements > visible"और देखें ({n} और)" link at the bottom; tap loads next 5 from server.
timeline.size ≥ timelineTotalElements"और देखें" link disappears; full history shown.
Drilldown dismissedonDismissTaskDrilldown resets unseenCount = 0; badge + tints clear on next open.
In-session morph (e.g. CSP assigns tech)VM appends a synthetic TimelineEventInfo locally + bumps unseenCount so §2 re-expands and the new row is tinted.

Install vs Restore — differences

AspectInstall (StatusTimelineCard)Restore (RestoreTimelineSection)
Title label keyscheduling_timeline → "अपडेट"event_timeline → "अपडेट"
Empty label keytimeline.empty → "अभी कोई अपडेट नहीं"same (shared)
PaginationServer-side, BE-driven, 5-per-page via /install/candidates/{id}/timelineClient-side cap at 5 visible; "और देखें" toggles to show-all in the same payload
Code locationInstallDrilldownContent.kt:437RestoreDrilldownContent.kt:392

Worked example: Wiom wants to nudge a slow CSP

Scenario: An install task is in AWAITING_TECHNICIAN_ASSIGNMENT, the slot day is approaching, and Wiom decides the CSP needs to hurry up. Where does that message live — banner or अपडेट?

Short answer: The "hurry up" lives in the अपडेट section, not the banner. Banner reflects task state; अपडेट carries events. A nudge is an event, not a state change.

How the nudge cascades through the app

Wiom's backend doesn't transition the state — it pushes one new TimelineEventInfo with unseenCount bumped. That single signal lights up multiple surfaces:

SurfaceWhat changesWhy
अपडेट sectionNew row at top with pink-tint background: "जल्दी करें — स्लॉट 2 घंटे में शुरू, टीम मेम्बर चुनें"This is the actual carrier of the message
अपडेट badgePink "1" count next to the section titleDriven by unseenCount bump
अपडेट auto-expandSection auto-opens on next drilldown entryexpanded = remember(unseenCount) { unseenCount > 0 }
Home chip dotPink "new entry" dot on the नया काम chiphasNewEntry = true flows up to the chip
Task feed rowCard gets a pink dot, may move upSame unseenCount signal
Bell iconNotification badge incrementsPush channel mirrors the timeline entry
Banner titleUnchanged — still "टेक्निशियन चुनना बाकी है"State didn't change — still AWAITING_TECHNICIAN_ASSIGNMENT
Banner severity (optional)Can flip warningnegative if Wiom decides it's criticalRequires a server-side severity bump, not just a timeline event
Countdown pillthresholdState: NORMAL → URGENT → OVERDUE, yellow → redTime-based, independent of the message

What the partner sees, step by step

  1. Wiom backend posts the nudge → push notification arrives on the phone.
  2. CSP opens the app → the नया काम chip on Home has a pink dot.
  3. CSP taps into the task drilldown.
  4. Banner is still warning yellow, still saying "टेक्निशियन चुनना बाकी है" — but the deadline pill now reads "2 घंटे बाकी" in urgent colour.
  5. अपडेट section is auto-expanded with a pink "1" badge.
  6. The new row sits at the top, pink-tinted:
📈 अपडेट 1
जल्दी करें — स्लॉट 2 घंटे में शुरू, टीम मेम्बर चुनें अभी
कनेक्शन ने स्लॉट 1 चुना 11 Apr, 11:00 AM

Why this design is intentional

  1. Banner is predictable: the title is a function of state. If "hurry up" messages overwrote the banner, the CSP would never know whether the visible copy reflects the actual task state or a transient nudge.
  2. History is preserved: a nudge in अपडेट stays visible forever (paginated). The CSP can scroll back and see "Wiom told me to hurry at 10:14 AM" even after they've taken action.
  3. One signal, many surfaces: bumping unseenCount is the single switch that lights up the chip dot, section badge, task card dot, and bell — without each surface needing its own urgency channel.

The dividing line — when banner WOULD change

Soft signal → अपडेट

  • "जल्दी करें" reminder
  • "स्लॉट का समय पास" warning
  • Wiom support message
  • Any nudge where the task's underlying state is still the same

Hard transition → Banner

  • Deadline lapsed → task auto-morphs to NEEDS_RESCHEDULING → banner flips to "कनेक्शन के लिए नया समय चुनें"
  • Customer denies access → state becomes CUSTOMER_DENIED
  • Wiom escalates / takes over → state changes to ESCALATED_PLATFORM_TAKEOVER
Rule of thumb: soft "hurry up" → अपडेट. Hard "state has changed" → banner.

Banner colour families — visual reference