1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3691],{454:(e,o,n)=>{n.d(o,{EH:()=>el,dq:()=>ec});var t=n(78129),r=n(27667),s=n(97599),a=n(67081),i=n(1940),d=n(70222),l=n(4968),c=n(37230),u=n(87500),h=n(34788),p=n(25352),m=n(96205),w=n(73731),v=n(64287),k=n(28451),b=n(10111),f=n(44626),y=n(92538),g=n(3972),A=n(48272),_=n(66423),R=n(56531),S=n(70077),x=n(89131),N=n(91551),j=n(9453),C=n(20399),D=n(33725),I=n(65896),q=n(39062),P=n(56978),T=n(49539),M=n(23192),W=n(94168),E=n(85361),O=n(57809),F=n(84107),Q=n(34227),B=n(61475),L=n(64989),V=n(35354),J=n(73053),H=n(56582),U=n(85771),K=n(67367),z=n(83437),G=n(64712),X=n(31631),Y=n(89840),$=n(8731),Z=n(86005),ee=n(8316),eo=n(70160),en=n(27906),et=n(50370),er=n(41068),es=n(66351),ea=n(33276),ei=n(28570);let ed={edit:t.A,delete:r.A,restore:s.A,duplicate:a.A,merge:i.A,copy:a.A,open:d.A,print:l.A,search:c.A,settings:u.A,close:h.A,confirm:p.A,undo:m.A,redo:w.A,hide:v.A,unhide:k.A,block:b.A,unblock:f.A,mark_read:y.A,mark_unread:g.A,open_customer:A.A,convert_lead:_.A,sign_up_customer:_.A,new_customer:_.A,new_job:R.A,new_hire:S.A,new_scheduled:x.A,new_service:N.A,message_day:j.A,reoptimise:C.A,plan_trip:D.A,reoptimise_all:I.A,sequence:q.A,move_day:P.A,skip:T.A,navigate:M.A,report_issue:W.A,alerts:E.A,reminder:O.A,warning:F.A,office:Q.A,photo:B.A,voice_note:L.A,receipts:V.A,forecast:P.A,quote:J.A,notes:H.A,appointment:U.A,done:p.A,done_paid:K.A,replan:z.A,assign:A.A,refund:G.A,void_document:X.A,request_payment:Y.A,email:$.A,upload:Z.A,attach:ee.A,import_data:eo.A,download:en.A,preview:k.A,invoice:V.A,payment:et.A,money:er.A,bins:es.A,truck:S.A,call:ea.A,message:j.A,add:ei.A},el=20;function ec(e){let o=ed[e];if(!o)throw Error('no glyph for the concept "'.concat(e,'"; add it to lib/ui/waiste-verb-icons.ts'));return o}},10583:(e,o,n)=>{n.d(o,{As:()=>l,FB:()=>h,ft:()=>c,gh:()=>p,kh:()=>s,rv:()=>r,sv:()=>i});var t=n(34998);function r(e){return"overdue"===e?"--st-record-overdue":"done"===e||"paid"===e?"--st-record-done":"skipped"===e?"--st-record-skipped":"--st-record-due"}function s(e,o){var n;let s=null!=(n=e.status)?n:"",a=function(e,o){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:o;return{tone:e,colourToken:r(e),label:o,badge:n}};return"done"===s||"completed"===s?!0===e.invoicePaid?a("paid","Done & paid"):a("done","Done"):"skipped"===s||"failed"===s||"cancelled"===s?a("skipped",t.Kd[s].word):e.date<o?a("overdue","Overdue"):a("due","Due",e.date===o?"Due today":"Scheduled")}let a={good:"ok",progress:"info",bad:"bad",warn:"warn",muted:"neutral",scheduled:"neutral"};function i(e){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("scheduled"===e)return o.overdue?{word:"Overdue",tone:"bad"}:o.today?{word:"Due today",tone:"info"}:{word:o.dateShort?"Scheduled ".concat(o.dateShort):"Scheduled",tone:"neutral"};let n=(0,t.E7)("stop",e);return n?{word:n.word,tone:a[n.tone],..."in_progress"===e?{pulse:!0}:{}}:{word:e.replace(/_/g," "),tone:"neutral"}}let d=["done","paid","skipped"];function l(e){return null!=e&&d.includes(e)}function c(e){var o,n;let t=String(null!=(o=e.status)?o:"");return"done"===t||"delivered"===t||"collected"===t||"exchanged"===t?(null==(n=e.invoice)?void 0:n.state)==="paid"?"paid":"done":"skipped"===t||"failed"===t||"missed"===t?"skipped":null}let u=e=>"".concat(e.getFullYear(),"-").concat(String(e.getMonth()+1).padStart(2,"0"),"-").concat(String(e.getDate()).padStart(2,"0"));function h(e,o){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new Date,t="paid"===e,r=s({date:u(o),status:t?"done":null!=e?e:null,invoicePaid:t},u(n));return{key:"due"===r.tone?"upcoming":r.tone,color:"var(".concat(r.colourToken,")"),label:r.label,badge:r.badge}}function p(e){return"var(".concat(r(e),")")}},13677:(e,o,n)=>{n.d(o,{N:()=>r,R:()=>t});let t="settings";function r(e){return e===t?"/app/settings":"/app/settings?".concat(new URLSearchParams({section:e}).toString())}},13691:(e,o,n)=>{n.d(o,{F:()=>v,X:()=>k});var t=n(95155),r=n(12115),s=n(47650),a=n(90877),i=n(67699),d=n(96160),l=n(454),c=n(25565),u=n(41571),h=n(10968),p=n(90920),m=n(36652);function w(e){var o;let n={ArrowDown:1,ArrowUp:-1}[e.key];if(!n&&"Home"!==e.key&&"End"!==e.key)return;let t=[...e.currentTarget.querySelectorAll('[role^="menuitem"]:not([disabled])')];if(!t.length)return;e.preventDefault();let r=t.indexOf(document.activeElement),s="Home"===e.key?0:"End"===e.key?t.length-1:(r+n+t.length)%t.length;null==(o=t[s])||o.focus()}function v(e,o){return e.map(e=>{var n,t,r,s,a;let i=null!=(n=o[e.key])?n:{},c=e.countable?(null!=(t=i.count)?t:"").length>0?e.label.replace(e.countable,i.count):e.label.replace(e.countable,"").replace(/\s{2,}/g," ").trim():e.label,u=!!e.unavailable||!!i.refusal||!!i.busy;return{key:e.key,label:c,hint:null!=(s=null!=(r=i.refusal)?r:e.unavailable)?s:e.hint,icon:(0,l.dq)(e.verb),href:u?void 0:null!=(a=i.href)?a:"href"===e.door.kind?e.door.href:void 0,onSelect:u?void 0:i.onSelect,disabled:u,confirm:d.Er.has(e.key)?"money":e.stopVerb||"runningLate"===e.key?"spoken":void 0,ask:i.ask}})}function k(e){var o,n,d;let{open:l,onClose:v,rows:k,title:b,slot:f,mode:y="sheet",at:g,width:A,cancelLabel:_="Cancel",closeOnSelect:R=!0,tone:S=null,children:x}=e,N=(0,m.iK)(),j="popover"===y&&N?"sheet":y,C=(0,u.fe)(),D=(0,u.km)(),I=(0,r.useRef)(null),q=null==(o=(0,a.useDialogKeys)(I,l&&D,v,void 0,{modal:"popover"!==j}))?void 0:o.child,P=A?{width:A,minWidth:A,maxWidth:A}:null,[T,M]=(0,r.useState)(!1);(0,r.useEffect)(()=>M(!0),[]),(0,r.useEffect)(()=>
1{if(!l||"popover"!==j)return;let e=e=>{I.current&&!I.current.contains(e.target)&&v()};return document.addEventListener("pointerdown",e,!0),()=>document.removeEventListener("pointerdown",e,!0)},[l,j,v]);let W=null!=(n=null==g?void 0:g.x)?n:null,E=null!=(d=null==g?void 0:g.y)?d:null,[O,F]=(0,r.useState)(null);(0,r.useEffect)(()=>{if(!l||"popover"!==j||null===W||null===E)return void F(null);let e=I.current;if(!e)return;let o={width:e.offsetWidth,height:e.offsetHeight},n=(0,i.Iy)({at:{x:W,y:E},menu:{width:o.width,height:o.height},viewport:{width:window.innerWidth,height:window.innerHeight}});F({left:n.left,top:n.top})},[l,j,W,E,k,T]);let[Q,B]=(0,r.useState)(0),L=(0,r.useRef)(0);(0,r.useLayoutEffect)(()=>{let e=I.current;if(!l||"popover"!==j||null!==W||!e){L.current=0,B(0);return}let o=e.getBoundingClientRect();if(!o.width)return;let n=o.left-L.current,t=o.right-L.current,r=n<8?8-n:t>window.innerWidth-8?Math.max(8-n,window.innerWidth-8-t):0;L.current=r,B(r)},[l,j,W,k.length,T]);let{present:V,state:J}=(0,c._9)(l,"sheet"===j?"sheet":"menu");if(!V)return null;let H=(0,t.jsx)("ul",{role:"menu","aria-label":null!=b?b:"Actions",className:"w-actions navigation-list",onKeyDown:w,children:k.map(e=>{let o=e.icon;if(e.heading)return(0,t.jsx)("li",{role:"presentation",className:"w-actions__heading","data-slot":"actions.heading",children:e.label},e.key);let n=(0,t.jsxs)(t.Fragment,{children:[e.lead?(0,t.jsx)("span",{className:"w-actions__icon setting-icon grid place-items-center","data-lead":"","aria-hidden":"true",children:e.lead}):o?(0,t.jsx)(o,{size:20,strokeWidth:1.75,className:"w-actions__icon setting-icon","aria-hidden":!0}):(0,t.jsx)("span",{className:"w-actions__icon setting-icon","aria-hidden":"true"}),(0,t.jsxs)("span",{className:"w-actions__text setting-text",children:[(0,t.jsx)("span",{className:"w-actions__label",children:e.label}),e.hint?(0,t.jsx)("span",{className:"w-actions__hint",children:e.hint}):null]}),null!=e.count?(0,t.jsx)("span",{className:"w-actions__count","data-slot":"actions.count",children:e.count}):null,e.selected?(0,t.jsx)(p.jq,{name:"check",size:18,className:"w-actions__tick"}):null,null!=e.expanded?(0,t.jsx)("span",{className:"w-actions__chevron","data-open":e.expanded?"true":"false","aria-hidden":"true",children:(0,t.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round",strokeLinejoin:"round",children:(0,t.jsx)("path",{d:"M9 18l6-6-6-6"})})}):null]}),r="w-actions__row".concat(e.destructive?" is-destructive":"").concat(e.selected?" is-selected":"");return(0,t.jsx)("li",{role:"none",children:e.href&&!e.disabled?(0,t.jsx)("a",{role:"menuitem",href:e.href,target:e.href.startsWith("http")||e.href.startsWith("geo")?"_blank":void 0,rel:"noreferrer",onClick:v,className:r,children:n}):(0,t.jsx)("button",{type:"button",role:null!=e.selected?"menuitemradio":"menuitem","aria-checked":null!=e.selected?e.selected:void 0,"aria-expanded":null!=e.expanded?e.expanded:void 0,"data-depth":e.depth?String(e.depth):void 0,disabled:e.disabled,onClick:()=>{var o;e.disabled||(R&&v(),null==(o=e.onSelect)||o.call(e))},className:r,children:n})},e.key)})});if("popover"===j){if(!D)return null;if(null===W||null===E)return(0,t.jsxs)("div",{ref:I,role:"dialog","aria-modal":"false","aria-label":null!=b?b:"Actions","data-slot":f,className:"w-actions-popover",style:{...P,...Q?{transform:"translateX(".concat(Q,"px)")}:null},children:[b?(0,t.jsx)("div",{className:"w-actions__title",children:b}):null,x,H]});let e=(0,t.jsxs)("div",{ref:I,role:"dialog","aria-modal":"false","data-slot":f,"aria-label":null!=b?b:"Actions","data-at-pointer":"true",className:"w-actions-popover is-at-pointer w-ovl-menu","data-state":J,style:{...C?{zIndex:h.Gf+1}:null,...O?{...P,left:O.left,top:O.top}:{...P,left:W,top:E,visibility:"hidden"}},children:[b?(0,t.jsx)("div",{className:"w-actions__title",children:b}):null,x,H]});return T?(0,s.createPortal)(e,(0,a.portalRoot)()):null}if(!D)return null;let U=(0,t.jsx)("div",{className:"w-sheet-scrim w-ovl-dialog-scrim",style:C?{zIndex:h.Gf+1}:void 0,"data-state":J,"data-child":q?"":void 0,role:"presentation",onClick:v,children:(0,t.jsxs)("div",{ref:I,role:"dialog","aria-modal":"true","aria-label":null!=b?b:"Actions","data-slot":f,className:"w-actions-sheet w-ovl-dialog".concat("dark"===S?" nav
1-ink":""),"data-state":J,onClick:e=>e.stopPropagation(),children:[b?(0,t.jsx)("div",{className:"w-actions__title",children:b}):null,x,H,(0,t.jsx)("button",{type:"button",onClick:v,className:"w-actions__cancel",children:_})]})});return T?(0,s.createPortal)(U,(0,a.portalRoot)()):null}},67699:(e,o,n)=>{function t(e){var o;let n=null!=(o=e.margin)?o:8,{at:t,menu:r,viewport:s}=e,a=t.x,i=!1;a+r.width+n>s.width&&(a=t.x-r.width,i=!0),a<n&&(a=n);let d=t.y,l=!1;return d+r.height+n>s.height&&(d=t.y-r.height,l=!0),d<n&&(d=n),{left:a,top:d,flippedX:i,flippedY:l}}function r(e){return(e.anchorLeft+e.anchorRight)/2<e.viewportWidth/2?e.anchorLeft:e.anchorRight-e.menuWidth}function s(e){let o=e.getBoundingClientRect();return{x:Math.round(o.left),y:Math.round(o.bottom+4)}}n.d(o,{Iy:()=>t,qk:()=>s,qu:()=>r})},72596:(e,o,n)=>{n.d(o,{Bs:()=>t.Bs,Iu:()=>t.Iu,LP:()=>w,N6:()=>c,Te:()=>p,UV:()=>m,bR:()=>h,iy:()=>d,mb:()=>l,tu:()=>v});var t=n(95117);n(30761);var r=n(51020),s=n(10583);let a=(0,r.PC)(null),i=[{key:"date",label:"When",scope:"appointment",writer:"moveStopToDateAction"},{key:"start_time",label:"Time window",scope:"appointment",writer:"setStopWindowAction"},{key:"estimated_duration",label:"Duration",scope:"appointment",writer:"setStopDurationAction"},{key:"time_on_site",label:"Time on site",scope:"derived",writer:null},{key:"quantity",label:"Quantity",scope:"appointment",writer:"setStopQuantityAction"},{key:"note",label:"Driver note",scope:"appointment",writer:"setStopInstructionAction"},{key:"appointment_attachments",label:"".concat(a.one," attachments"),scope:"appointment",writer:null,viewer:"appointmentAttachments"},{key:"send_message",label:"Send message",scope:"appointment",writer:null},{key:"lock_replanning",label:"Lock replanning",scope:"job",writer:null},{key:"status",label:"Status",scope:"derived",writer:null},{key:"services",label:"Services",scope:"appointment",writer:"saveVisitServicesAction"},{key:"price",label:"Price",scope:"job",writer:"repriceAgreementAction",justThisWriter:null},{key:"discount",label:"Discount",scope:"job",writer:null},{key:"job_attachments",label:"Service attachments",scope:"job",writer:null,viewer:"jobAttachments"},{key:"round",label:"Round",scope:"job",writer:"assignAgreementAction",justThisWriter:null},{key:"recurrence",label:"Repeats",scope:"job",writer:"changeScheduleAction",justThisWriter:"moveStopToDateAction"}];function d(e){var o;let n=[];return e.stopInstruction&&n.push("the driver instruction"),e.binQuantity&&e.binQuantity.current!==e.binQuantity.standing&&n.push("the bin count"),(null==(o=e.duration)?void 0:o.from)==="job"&&n.push("the duration"),n}function l(e){let o=[];return"cancelled"===e.status&&o.push({key:"reinstate",label:"Reinstate job"}),("done"===e.status||"failed"===e.status||"skipped"===e.status)&&o.push({key:"correctOutcome",label:"Correct outcomeâ¦"}),"scheduled"===e.status&&e.releasedFromHold&&o.push({key:"revokeRelease",label:"Revoke hold releaseâ¦"}),o}function c(e){return i.map(o=>{var n;let t=e.values[o.key],r=null;"derived"===o.scope?r="time_on_site"===o.key?"Stamped when the driver taps Arrived and Done":"Worked out from the date and the outcome":null===o.writer?r="Waiste has no way to change this yet":e.computedOccurrence&&(r="This visit has not been scheduled onto a run yet");let s=null===r;return{key:o.key,label:o.label,scope:o.scope,value:null==t||""===t?"Not set":t,editable:s,viewable:!!o.viewer&&!e.computedOccurrence,asksRecurrence:s&&"job"===(n=o).scope&&null!==n.writer,writer:s?o.writer:null,readOnlyReason:r}})}let u=new Set(["scheduled","in_progress","planned","assigned"]);function h(e){return[...new Set(e.map(e=>e.disabledReason).filter(e=>!!e))]}function p(e){var o;if(e.computedOccurrence){let o=(e,o,n)=>({key:e,label:o,hint:n,sends:!1,notice:null,charges:!1,disabledReason:"This collection is not on a run yet, so there is nothing to record against it"}),n=[{key:"skip",label:"Skip",hint:"Take this date off the schedule before it is planned",sends:!1,notice:null,charges:!1,disabledReason:null},o("done","Done","Mark this stop complete"),o(t.Iu,"Done and paid","Finished, and the money was taken at the stop"),o("replan","Replan","Move this visit to another day"),o("assign","Assign","Give it to another vehicle or partner today"),o("repeat","Repeat job","Book this same job on another day")];return e.hasContact&&n.push({key:"messages",label:"View messages",hint:"This customer's thread",sends:!1,notice:null,charges:!1,disabledReason:null}),n}let n=u.has(e.status),r=[];
1return n&&(r.push({key:"done",label:"Done",hint:"Mark this stop complete",sends:!0,notice:"stop.complete",charges:!1,disabledReason:null}),r.push({key:t.Iu,label:"Done and paid",hint:"Finished, and the money was taken at the stop",sends:!0,notice:t.J3,charges:!0,disabledReason:e.paymentOnFile?null:t.$B}),r.push({key:"replan",label:"Replan",hint:"Move this visit to another day",sends:!0,notice:"run.move_stop_to_date",charges:!1,disabledReason:null}),r.push({key:"skip",label:"Skip",hint:"Not doing this one",sends:!0,notice:"run.mark_stop_missed",charges:!1,disabledReason:null})),n&&(null!=(o=e.moduleOutcomes)?o:[]).includes("futile")&&r.push({key:"futile",label:"Mark futile",hint:"We went, and the work could not be done",sends:!0,notice:"run.mark_stop_missed",charges:!1,disabledReason:null}),e.canAssign&&r.push({key:"assign",label:"Assign",hint:"Give it to another vehicle or partner today",sends:!1,notice:null,charges:!1,disabledReason:null}),e.hasContact&&r.push({key:"messages",label:"View messages",hint:"This customer's thread",sends:!1,notice:null,charges:!1,disabledReason:null}),r.push({key:"repeat",label:"Repeat job",hint:"Book this same job on another day",sends:!0,notice:"collection.book",charges:!1,disabledReason:null}),r}function m(e,o){return(0,s.kh)({date:e.date,status:e.status},o).tone}function w(e){return(0,s.rv)(e)}function v(e){var o,n;let t=[...e.series].sort((e,o)=>e.date<o.date?-1:+(e.date>o.date)),r=null!=(o=t.filter(o=>o.date<e.currentDate).at(-1))?o:null,s=null!=(n=t.find(o=>o.date>e.currentDate))?n:null,a=o=>null===o?null:{occurrence:o,distance:function(e){if(0===e)return"Today";if(1===e)return"Tomorrow";if(-1===e)return"A day ago";let o=function(e){if(e<7)return 1===e?"a day":"".concat(e," days");if(e<28){let o=Math.floor(e/7),n=e%7,t=1===o?"a week":"".concat(o," weeks");return 0===n?t:"".concat(t,", ").concat(1===n?"1 day":"".concat(n," days"))}let o=Math.round(e/30);return o<=1?"a month":"".concat(o," months")}(Math.abs(e));return e>0?"In ".concat(o):"".concat(o," ago")}(e.daysFromCurrent(o.date)),tone:m(o,e.today)};return{previous:a(r),next:a(s)}}},95117:(e,o,n)=>{n.d(o,{$B:()=>i,Bs:()=>a,Iu:()=>r,J3:()=>s,jP:()=>d});var t=n(42738);let r="done_and_paid",s="stop.done_and_paid",a="stop.done_and_paid",i="No card on file for this customer, so there is nothing to charge. Add a card, or use Done and invoice them.";function d(e){var o;if(null===e.totalCents||!Number.isFinite(e.totalCents))return null;let n=(0,t.up)(e.totalCents),r=null!=(o=e.method)?o:"cash",s="card"===r?"".concat(n," will be charged to the card on file"):"".concat(n," will be recorded as paid by ").concat("cash"===r?"cash":"another method"),a=e.notify?" and a receipt goes to the customer":" and nothing is sent to the customer";return"Done and paid: ".concat(s).concat(a,".")}},96160:(e,o,n)=>{n.d(o,{Er:()=>c,Fx:()=>k,HL:()=>g,NK:()=>u,VQ:()=>f,lK:()=>b,m5:()=>A});var t=n(55018),r=n(72596),s=n(51020),a=n(13677),i=n(56836),d=n(89303);let l=(0,s.PC)(null),c=new Set(["payment","refund","donePaid"]),u=["navigateNext","done","skip","runningLate","addNote","callCustomer"],h="core customer door: every operator has customers, their money and their messages, module or none",p="core customer book: the list, its duplicates and its imports exist for every operator",m="core record door: a record's files and its invoice are the same shape for every module",w="core stop door: a stop is completed, moved or skipped the same way for every module",v={kind:"reference"},k={addNewJob:{key:"addNewJob",label:"Add New Job",hint:"Ad hoc or recurring, on the one job form",verb:"new_job",colour:"var(--dial-new-job)",door:{kind:"host"},source:v,owner:"core",ownerReason:"core day door: every operator has a day with work on it, whatever service that work is",action:null,sends:{kind:"own-door",door:"components/ops/waiste-book-collection.tsx"}},createQuote:{key:"createQuote",label:"Create A Quote",hint:"Opens the quote door",verb:"quote",colour:"var(--dial-quote)",door:{kind:"href",href:"".concat(i.UP,"&new=1")},source:v,owner:"core",ownerReason:h,action:null,sends:{kind:"never"}}
1,done:{key:"done",label:"Done",hint:"Mark this stop complete",verb:"done",colour:"var(--dial-done)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,action:"stop.complete",sends:{kind:"own-door",door:"lib/ui/waiste-stop-record-sheet.ts stopRecordActions done"},stopVerb:"done"},donePaid:{key:"donePaid",label:"Done And Paid",hint:"Finished, and the money was taken at the stop",verb:"done_paid",colour:"var(--dial-done-paid)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,stopVerb:r.Iu,action:r.Bs,sends:{kind:"own-door",door:"lib/actions doneAndPaidStopAction, declaring ACTION_NOTICES stop.done_and_paid - the receipt AND this stop's own customer notice"}},replan:{key:"replan",label:"Replan",hint:"Move this visit to another day",verb:"replan",colour:"var(--dial-replan)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,action:"run.move_stop_to_date",sends:{kind:"own-door",door:"lib/ui/waiste-stop-record-sheet.ts stopRecordActions replan"},stopVerb:"replan"},skip:{key:"skip",label:"Skip",hint:"Not doing this one",verb:"skip",colour:"var(--dial-skip)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,action:"run.mark_stop_missed",sends:{kind:"own-door",door:"lib/ui/waiste-stop-record-sheet.ts stopRecordActions skip"},stopVerb:"skip"},assign:{key:"assign",label:"Assign",hint:"Give it to another vehicle or partner today",verb:"assign",colour:"var(--dial-assign)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,action:"job.move_run",sends:{kind:"never"},stopVerb:"assign"},messages:{key:"messages",label:"View Messages",hint:"This customer's thread",verb:"message",colour:"var(--dial-messages)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,action:null,sends:{kind:"never"},stopVerb:"messages"},payment:{key:"payment",label:"Payment",hint:"Money already taken, against what is owing",verb:"payment",colour:"var(--dial-payment)",door:{kind:"host"},source:v,owner:"core",ownerReason:h,action:"invoice.mark_paid",sends:{kind:"own-door",door:"components/ops/customer-room RecordPaymentSheet"}},refund:{key:"refund",label:"Refund",hint:"A refund goes back against the payment that was taken",verb:"refund",colour:"var(--dial-refund)",door:{kind:"host"},source:v,owner:"core",ownerReason:h,action:"payment.refund",sends:{kind:"own-door",door:"lib/actions refundPaymentAction, from the invoice"},unavailable:"Open the invoice that was paid - a refund goes back against that payment"},sendMessage:{key:"sendMessage",label:"Send Message",hint:"Opens the conversation with the composer",verb:"message",colour:"var(--dial-message)",door:{kind:"href-from-host"},source:v,owner:"core",ownerReason:h,action:null,sends:{kind:"never"}},createInvoice:{key:"createInvoice",label:"Create Invoice",hint:"Creates an invoice for this customer",verb:"invoice",colour:"var(--dial-invoice)",door:{kind:"host"},source:v,owner:"core",ownerReason:h,action:"invoice.create_custom",sends:{kind:"own-door",door:"components/ops/waiste-job-form.tsx"}},requestPayment:{key:"requestPayment",label:"Request Payment",hint:"Asking for money goes out against one invoice",verb:"request_payment",colour:"var(--dial-request-payment)",door:{kind:"host"},source:v,owner:"core",ownerReason:h,action:"invoice.send",sends:{kind:"own-door",door:"lib/actions sendInvoiceAction, behind the invoice send confirm"},unavailable:"Open the invoice you want paid - the request goes out from there"},editJob:{key:"editJob",label:"Edit Job",hint:"Open the shared job details form",verb:"edit",colour:"var(--dial-edit)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,action:null,sends:{kind:"never"}},addAppointment:{key:"addAppointment",label:"Add ".concat(l.one),hint:"Booking a visit asks for its date inside Add New Job",verb:"appointment",colour:"var(--dial-appointment)",door:{kind:"host"},source:v,owner:"core",ownerReason:w,action:null,sends:{kind:"never"},unavailable:"Waiste books the visit and its date together - use Add New Job"},emailInvoice:{key:"emailInvoice",label:"Email Invoice",hint:"Opens the invoice, where the send asks you to confirm first",verb:"email",colour:"var(--dial-email)",door:{kind:"href-from-host"},source:v,owner:"core",ownerReason:m,action:"invoice.send",sends:{kind:"own-door",door:"components/ops/invoice-actions.tsx InvoiceActions"}},smsInvoice:{key:"smsInvoice",label:"SMS Invoice",hint:"Opens the invoice, where the send asks you to confirm first",verb:"message",colour:"var(--dial-sms)",door:{kind:"href-from-host"},source:v,owner:"core",ownerReason:m,action:"invoice.send",sends:{kind:"own-door",door:"components/ops/invoice-actions.tsx InvoiceActions"}},previewInvoice:{key:"previewInvoice",label:"Preview Invoice",hint:"The full tax invoice, as the customer receives it",verb:"preview",colour:"var(--dial-preview)",door:{kind:"href-from-host"},source:v,owner:"core",ownerReason:m,action:null,sends:{kind:"never"}},downloadInvoice:{key:"downloadInvoice",label:"Download",hint:"The PDF, from the invoice page",verb:"download",colour:"var(--dial-download)",door:{kind:"href-from-host"},source:v,owner:"core",ownerReason:m,action:null,sends:{kind:"never"}},uploadFile:{key:"uploadFile",label:"Upload File",hint:"A photo or a document onto this record",verb:"upload",colour:"var(--dial-upload)",door:{kind:"host"},source:v,owner:"core",ownerReason:m,action:null,sends:{kind:"never"}},selectExisting:{key:"selectExisting",label:"Select Existing Attachments",hint:"A file already on another record",verb:"attach",colour:"var(--dial-attach)",door:{kind:"host"},source:v,owner:"core",ownerReason:m,action:null,sends:{kind:"never"}
1,unavailable:"Linking a file that is already on another record is not built yet - upload it here instead"},addCustomer:{key:"addCustomer",label:"Add New Customer",hint:"The room's create door",verb:"new_customer",colour:"var(--dial-new-customer)",door:{kind:"href-from-host"},source:v,owner:"core",ownerReason:p,action:null,sends:{kind:"never"}},mergeCustomers:{key:"mergeCustomers",label:"Merge Customers",hint:"Two records for one customer, joined into one",verb:"merge",colour:"var(--dial-merge)",door:{kind:"host"},source:v,owner:"core",ownerReason:p,action:"customer.merge",sends:{kind:"never"}},checkDuplicates:{key:"checkDuplicates",label:"Check Potential Duplicate Customers",hint:"The data quality book",verb:"search",colour:"var(--dial-merge)",door:{kind:"href",href:"/app/customers?f.show=fix"},source:v,owner:"core",ownerReason:p,action:null,sends:{kind:"never"}},restoreCustomer:{key:"restoreCustomer",label:"Restore Deleted Customer",hint:"Open the customer and use Archive again to bring them back",verb:"restore",colour:"var(--dial-restore)",door:{kind:"href",href:"/app/customers?f.show=fix"},source:v,owner:"core",ownerReason:p,action:null,sends:{kind:"never"}},importCustomers:{key:"importCustomers",label:"Import Customers",hint:"The spreadsheet importer",verb:"import_data",colour:"var(--dial-import)",door:{kind:"href",href:(0,a.N)("import")},source:v,owner:"core",ownerReason:p,action:null,sends:{kind:"never"}},hireRun:{key:"hireRun",label:"Add hire run",hint:"A run for today's deliveries and collections",verb:"truck",colour:"var(--dial-add)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no hire: a Waiste day can carry a run of bin deliveries and collections, and the DAY'S OWN data (data.hireDeliveryDay) decides whether the row is offered"}
1,owner:"core",ownerReason:"gated by the DAY'S OWN deliveries (data.hireDeliveryDay), which only a hire-shaped module can produce - so it is module-specific WITHOUT this file learning a module's name",action:null,sends:{kind:"never"}},futile:{key:"futile",label:"Mark futile",hint:"We went, and the work could not be done",verb:"warning",colour:"var(--dial-futile)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference job dial has no futile outcome; Waiste offers it only where the MODULE MANIFEST declares it, and stopRecordActions decides that - so the row is declared here and appears only when that function returns the verb"},owner:"core",ownerReason:w,action:"stop.complete",sends:{kind:"own-door",door:"lib/ui/waiste-stop-record-sheet.ts stopRecordActions futile"},stopVerb:"futile"},createService:{key:"createService",label:"Create New Service",hint:"A new thing this business sells, with its own rate",verb:"new_service",colour:"var(--dial-new-service)",door:{kind:"host"},source:v,owner:"core",ownerReason:"the price book is core - every module sells something and the catalogue is one list, so no single module owns the verb that adds to it",action:null,sends:{kind:"never"}},createContractor:{key:"createContractor",label:"Add partner",hint:"A firm you subcontract work to, with its own run sheet or driver-app access",verb:"new_customer",colour:"var(--dial-new-customer)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no contractors screen; the owner rejected a footer button under the list on 15 Sep 2026 ('should be styled same as the services list'), and the services room's own Add door is this same dial shape, so the contractor room copies it rather than keeping a lookalike button"},owner:"core",ownerReason:"a subcontracted firm can carry any module's runs, so no single module owns the door that adds one",action:null,sends:{kind:"never"}},findPartners:{key:"findPartners",label:"Find partners",hint:"Businesses on the Waiste network by work, size, waste and area, and your partners not on Waiste yet",verb:"search",colour:"var(--dial-new-customer)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no network screen; master X.25 rules the directory is not a page but what sits behind the Providers list's add button, so it is this dial's second row and opens a sheet"},owner:"core",ownerReason:"any business can send work to a partner whatever it sells, so no single module owns finding one",action:null,sends:{kind:"own-door",door:"components/ops/waiste-invite-to-waiste.tsx"}},createVehicle:{key:"createVehicle",label:"Add vehicle",hint:"Number plate, name and type; capacity and routing are set on the record after",verb:"new_customer",colour:"var(--dial-new-customer)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no vehicles screen; the owner's 15 Sep 2026 ruling ('should be styled same as the services list') moved this fleet's own Add door off a footer button under the list and onto the dial, the same shape createContractor and createService already took"},owner:"core",ownerReason:"a vehicle can carry any module's runs, so no single module owns the door that adds one to the fleet",action:null,sends:{kind:"never"}},sendQuote:{key:"sendQuote",label:"Send Quote",hint:"Email or text the quote with its accept link; you confirm first",verb:"quote",colour:"var(--dial-quote)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no quotes screen; owner order 14 Sep 2026, 'quotes ui page should be a clone of the bookings ui ... with quote specific fab like send quote delete etc'"},owner:"core",ownerReason:h,action:null,sends:{kind:"own-door",door:"components/ops/waiste-quote-send.tsx"}},convertQuote:{key:"convertQuote",label:"Book The Work",hint:"Turn the accepted quote into its jobs, once",verb:"confirm",colour:"var(--dial-add)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no quotes screen; owner order 14 Sep 2026, the Quotes room's dial books an accepted quote through the one conversion door"},owner:"core",ownerReason:h,action:null,sends:{kind:"own-door",door:"components/ops/waiste-quote-convert.tsx"}},deleteQuote:{key:"deleteQuote",label:"Delete Draft",hint:"Remove an unsent draft; a sent or answered quote stays on file",verb:"delete",colour:"var(--dial-edit)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no quotes screen; owner order 14 Sep 2026 names delete as a quote-specific row, limited to drafts nothing depends on"},owner:"core",ownerReason:h,action:null,sends:{kind:"never"}},newHire:{key:"newHire",label:"New Hire",hint:"A bin delivered and collected, booked from here",verb:"truck",colour:"var(--dial-add)",door:{kind:"href",href:"/app/new-job"},source:{kind:"waiste-add",reason:"Bookings includes New hire alongside its other supported creation actions"},owner:"ongoing_collections",ownerReason:"the door it opens is the hire booking flow; a business with no hire module has nowhere honest for this row to land",action:null,sends:{kind:"never"}},reportIssue:{key:"reportIssue",label:"Report an issue",hint:"Tell the office something is wrong with the app or this stop",verb:"report_issue",colour:"var(--st-warn)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no driver app; owner ruling 29 Aug 2026 put Report an issue inside the driver's floating menu on the stop page"},owner:"core",ownerReason:"every driver of every module can hit a fault, so no single module owns reporting one",action:null,sends:{kind:"never"}},replySms:{key:"replySms",label:"Reply by SMS",hint:"Opens the reply on SMS; you confirm before it sends",verb:"message",colour:"var(--dial-sms)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no messages screen; owner order 28 Sep 2026 gave a thread's orb its reply, call, book and note rows"},owner:"core",ownerReason:h,action:null,sends:{kind:"own-door",door:"app/app/comms/waiste-comms-workspace.tsx Composer, behind the one send sheet"}},replyEmail:{key:"replyEmail",label:"Reply by email",hint:"Opens the reply on email; you confirm before it sends",verb:"email",colour:"var(--dial-email)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no messages screen; owner order 28 Sep 2026 gave a thread's orb its reply, call, book and note rows"},owner:"core",ownerReason:h,action:null,sends:{kind:"own-door",door:"app/app/comms/waiste-comms-workspace.tsx Composer, behind the one send sheet"}},callCustomer:{key:"callCustomer",label:"Call",hint:"Rings the number on this thread",verb:"call",colour:"var(--dial-messages)",door:{kind:"href-from-host"},source:{kind:"waiste-add",reason:"the reference has no messages screen; owner order 28 Sep 2026 gave a thread's orb its reply, call, book and note rows"},owner:"core",ownerReason:h,action:null,sends:{kind:"never"}},bookFromMessage:{key:"bookFromMessage",label:"Book from this message",hint:"The booking card, filled from what they wrote",verb:"new_job",colour:"var(--dial-new-job)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no messages screen; owner order 28 Sep 2026 gave a thread's orb its reply, call, book and note rows"},owner:"core",ownerReason:h,action:null,sends:{kind:"own-door",door:"app/app/comms/waiste-comms-workspace.tsx ThreadBooking, behind its own confirm"}},addNote:{key:"addNote",label:"Add note",hint:"Staff only, never sent",verb:"notes",colour:"var(--dial-notes)",door:{kind:"host"},source:{kind:"waiste-add",reason:"the reference has no messages screen; owner order 28 Sep 2026 gave a thread's orb its reply, call, book and note rows"},owner:"core",ownerReason:h,action:null,sends:{kind:"never"}},navigateNext:{key:"navigateNext",label:"Navigate",hint:"Drive to the next stop",verb:"navigate",colour:"var(--dial-drive)",door:{kind:"host"},source:{kind:"waiste-add",reason:"owner order 29 Sep 2026: voice in the Day Pilot, a driver says Navigate and drives to the next stop"},owner:"core",ownerReason:w,action:null,sends:{kind:"never"}},runningLate:{key:"runningLate",label:"Running late",hint:"Tell the office, and the next customers if you choose",verb:"warning",colour:"var(--dial-reminders)",door:{kind:"host"},source:{kind:"waiste-add",reason:"owner order 29 Sep 2026: voice in the Day Pilot, a driver says Running late"},owner:"core",ownerReason:w,action:null,sends:{kind:"own-door",door:"the Day Pilot's Late notice (Notify / Don't notify), the one send sheet"}}};function b(e){return null===e.action?[]:(0,t.sr)(e.action)}let f=e=>"string"==typeof e?e:e.key,y=e=>"string"==typeof e?null:e.colour,g={job:{rows:["done","donePaid","replan","skip","assign","messages","futile"],dial:["done","skip","messages","assign"]},customer:{rows:["addNewJob","createQuote","payment","refund","sendMessage","createInvoice","requestPayment"],dial:["addNewJob","createQuote","payment","sendMessage"]},jobView:{rows:["editJob","addAppointment","createInvoice"]},invoice:{rows:["emailInvoice","smsInvoice","previewInvoice","downloadInvoice"]},attachments:{rows:["uploadFile","selectExisting"]},customers:{rows:["addCustomer","mergeCustomers","checkDuplicates","restoreCustomer","importCustomers"]}
1,shell:{rows:["addCustomer","addNewJob","createQuote"]},bookings:{rows:["addNewJob","addCustomer"]},quotes:{rows:["createQuote","addCustomer"]},bookingRecord:{rows:["addNewJob","createQuote","payment","refund","sendMessage","createInvoice","requestPayment"]},contractors:{rows:["createContractor","findPartners"]},driverStop:{rows:["reportIssue"]},thread:{rows:["replySms","replyEmail","callCustomer","bookFromMessage","addNote"]}};function A(e,o){var n;let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"all",s=g[e],a=new Set(null!=(n=o.absent)?n:[]),i=s.dial?new Set(s.dial):null,l=[];for(let e of s.rows){let n=f(e);if(i&&"dial"===r&&!i.has(n)||i&&"menu"===r&&i.has(n)||!i&&"menu"===r||a.has(n))continue;let s=k[n];if(!function(e,o){return"core"===e.owner||o.known&&o.modules.some(o=>(0,d.NH)(o)===e.owner)}(s,o.grants)||!function(e,o){let n=null===e.action?[]:(0,t.sr)(e.action);return 0===n.length||!o.known||n.every(e=>!1!==o.capabilities[e])}(s,o.permissions))continue;let c=y(e);l.push({...s,...c?{colour:c}:{},capabilities:b(s)})}return l}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.