Zgradi postopek odobritve stroškov od enega stanja do štirih, s pogojem, ki uveljavlja pravilo porabe.
Ta vodnik zgradi odobritev stroškov: zahtevek se pripravi, odda, nato odobri ali zavrne. Med potjo doda stanja, pogoje in zaslone za vsak korak. Dokončan orbital teče na dnu strani.
Začni s podatki. Zahtevek ima znesek in opombo; živi v pomnilniku, dokler je stran odprta.
1entity Expense [runtime] {
2 id : string!
3 amount : number = 120
4 note : string = ""
5}Vsaka lastnost potrebuje vsaj eno stanje in zaslon zanj. INIT se sproži, ko se stran odpre:
1app expense-step-2 "1.0.0"
2"Step 2: one state and its screen."
3orbital ExpenseOrbital {
4 entity Expense [runtime] {
5 id : string!
6 amount : number = 120
7 }
8
9 trait Approval -> Expense [interaction, instance] {
10 initial: draft
11
12 state draft {
13 INIT -> draft
14 (set @entity.amount 120)
15 (render-ui main { type: typography, content: (str/concat "Draft claim: " @entity.amount " EUR"), variant: h4 })
16 }
17 }
18
19 page "/expenses" -> Approval
20}Preveri ga z orb validate. Uspe: eno stanje, zaslon, stran, ki nekaj prikaže. Opazi (set @entity.amount 120): vsako polje, ki ga lastnost bere, mora nastaviti neki prehod. Nič ni privzeto.
Zahtevek se odda, nato odobri ali zavrne. Vsak korak je stanje in vsak gumb pošlje dogodek, ki ga sprejme neko stanje. Če dodaš gumb, katerega dogodka ne obravnava nobeno stanje, ga orb validate zavrne. Poskusi.
1state draft {
2 SUBMIT -> submitted
3 (render-ui main { type: stack, direction: horizontal, gap: sm, children: [
4 { type: button, label: "Approve", action: APPROVE, variant: primary },
5 { type: button, label: "Reject", action: REJECT, variant: secondary }
6 ] })
7}
8
9state submitted {
10 APPROVE -> approved
11 (set @entity.note "Approved")
12 REJECT -> rejected
13 (set @entity.note "Rejected")
14}Opazi, da tudi approved in rejected potrebujeta izhod: stanje brez izhodnega prehoda je slepa ulica in preverjevalnik to pove. Dokončana različica doda NEW_CLAIM in REVISE.
Pravilo podjetja: zahtevkov nad 500 EUR tu ni mogoče odobriti. Zapiši ga na prehod:
APPROVE -> approved when (<= @entity.amount 500)
(set @entity.note "Approved")Ko pogoj ne drži, je APPROVE zavrnjen in zahtevek ostane oddan. Pravilo živi na natanko enem mestu, preverjevalnik pa preizkusi obe strani.
Approval
on Expense · states: 4 · transitions: 7Zgornji program kot avtomati stanj, eden za vsako lastnost: vsak okvir je stanje, vsaka puščica dogodek, ki ga premakne, ikone na puščici pa so učinki, ki jih ta dogodek izvede. ◇ na puščici je varovalo; z miško pojdite nanj in preberite pogoj. Kako brati AVL
1app std-orb-docex-expense "1.0.0"
2"std-orb-docex-expense — an approval flow: four states, a guard on the amount, and a rule the shape of the program enforces."
3orbital ExpenseOrbital {
4 entity Expense [runtime] {
5 id : string!
6 amount : number = 120
7 note : string = ""
8 }
9
10 trait Approval -> Expense [interaction, instance] {
11 initial: draft
12
13 state draft {
14 INIT -> draft
15 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
16 { type: typography, content: (str/concat "Draft claim: " @entity.amount " EUR"), variant: h4 },
17 { type: stack, direction: horizontal, gap: sm, children: [
18 { type: button, label: "Add 50 EUR", action: RAISE, variant: ghost },
19 { type: button, label: "Submit", action: SUBMIT, variant: primary }
20 ] }
21 ] })
22 RAISE -> draft
23 (emit MOVED { event: "RAISE" })
24 (set @entity.amount (+ @entity.amount 50))
25 SUBMIT -> submitted when (> @entity.amount 0)
26 (emit MOVED { event: "SUBMIT" })
27 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
28 { type: typography, content: (str/concat "Submitted: " @entity.amount " EUR"), variant: h4 },
29 { type: typography, content: "Claims over 500 EUR cannot be approved here.", variant: small, color: muted },
30 { type: stack, direction: horizontal, gap: sm, children: [
31 { type: button, label: "Approve", action: APPROVE, variant: primary },
32 { type: button, label: "Reject", action: REJECT, variant: secondary }
33 ] }
34 ] })
35 }
36
37 state submitted {
38 APPROVE -> approved when (<= @entity.amount 500)
39 (emit MOVED { event: "APPROVE" })
40 (set @entity.note "Approved")
41 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
42 { type: badge, label: "Approved", variant: success },
43 { type: button, label: "New claim", action: NEW_CLAIM, variant: ghost }
44 ] })
45 REJECT -> rejected
46 (emit MOVED { event: "REJECT" })
47 (set @entity.note "Rejected")
48 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
49 { type: badge, label: "Rejected", variant: error },
50 { type: button, label: "Revise", action: REVISE, variant: primary }
51 ] })
52 }
53
54 state approved {
55 NEW_CLAIM -> draft
56 (emit MOVED { event: "NEW_CLAIM" })
57 (set @entity.amount 120)
58 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
59 { type: typography, content: (str/concat "Draft claim: " @entity.amount " EUR"), variant: h4 },
60 { type: stack, direction: horizontal, gap: sm, children: [
61 { type: button, label: "Add 50 EUR", action: RAISE, variant: ghost },
62 { type: button, label: "Submit", action: SUBMIT, variant: primary }
63 ] }
64 ] })
65 }
66
67 state rejected {
68 REVISE -> draft
69 (emit MOVED { event: "REVISE" })
70 (render-ui main { type: stack, direction: vertical, gap: sm, children: [
71 { type: typography, content: (str/concat "Draft claim: " @entity.amount " EUR"), variant: h4 },
72 { type: stack, direction: horizontal, gap: sm, children: [
73 { type: button, label: "Add 50 EUR", action: RAISE, variant: ghost },
74 { type: button, label: "Submit", action: SUBMIT, variant: primary }
75 ] }
76 ] })
77 }
78
79 emits {
80 MOVED -> external {
81 event : string!
82 }
83 @description "Each move names the event it took, so the diagram beside the demo can follow it."
84 }
85 }
86
87 page "/expenses" -> Approval
88}Kaj se zgodi, ko se sproži APPROVE:
(<= @entity.amount 500)(set @entity.note "Approved")Na njem zaženi orb verify: izvede se vsak prehod, pogoj se preizkusi z zneskom nad mejo in pod njo, preveri se vsak zaslon.
Zgradi upravljalnik opravil doda shranjene podatke in sezname.