-
Notifications
You must be signed in to change notification settings - Fork 17
/
Main.elm
4334 lines (3609 loc) · 151 KB
/
Main.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{--
Copyright (c) 2021 Target Brands, Inc. All rights reserved.
Use of this source code is governed by the LICENSE file in this repository.
--}
module Main exposing (main)
import Alerts exposing (Alert)
import Api
import Api.Endpoint
import Api.Pagination as Pagination
import Auth.Jwt exposing (JwtAccessToken, JwtAccessTokenClaims, extractJwtClaims)
import Auth.Session exposing (Session(..), SessionDetails, refreshAccessToken)
import Browser exposing (Document, UrlRequest)
import Browser.Dom as Dom
import Browser.Events exposing (Visibility(..))
import Browser.Navigation as Navigation
import Dict
import Errors exposing (Error, addErrorString, detailedErrorToString, toFailure)
import Favorites exposing (toFavorite, updateFavorites)
import FeatherIcons
import File.Download as Download
import Focus
exposing
( ExpandTemplatesQuery
, Fragment
, RefQuery
, focusFragmentToFocusId
, lineRangeId
, parseFocusFragment
, resourceFocusFragment
)
import Help.Commands
import Help.View
import Html
exposing
( Html
, a
, button
, details
, div
, footer
, h1
, header
, input
, label
, li
, main_
, nav
, p
, summary
, text
, ul
)
import Html.Attributes
exposing
( attribute
, checked
, class
, classList
, for
, href
, id
, name
, type_
)
import Html.Events exposing (onClick)
import Html.Lazy exposing (lazy, lazy2, lazy3, lazy4, lazy5, lazy7, lazy8)
import Http
import Http.Detailed
import Interop
import Json.Decode as Decode
import Json.Encode as Encode
import Maybe
import Nav exposing (viewUtil)
import Pager
import Pages exposing (Page(..))
import Pages.Build.Logs
exposing
( addLog
, bottomTrackerFocusId
, clickResource
, expandActive
, focusAndClear
, isViewing
, setAllViews
, updateLog
)
import Pages.Build.Model
import Pages.Build.View
import Pages.Builds exposing (view)
import Pages.Deployments.Model
import Pages.Deployments.Update exposing (initializeFormFromDeployment)
import Pages.Deployments.View
import Pages.Home
import Pages.Hooks
import Pages.Organization
import Pages.Pipeline.Model
import Pages.Pipeline.View
import Pages.RepoSettings exposing (enableUpdate)
import Pages.Secrets.Model
import Pages.Secrets.Update
import Pages.Secrets.View
import Pages.Settings
import Pages.SourceRepos
import RemoteData exposing (RemoteData(..), WebData)
import Routes exposing (Route(..))
import String.Extra
import SvgBuilder exposing (velaLogo)
import Task
import Time
exposing
( Posix
, Zone
, every
, here
, millisToPosix
, utc
)
import Toasty as Alerting exposing (Stack)
import Url exposing (Url)
import Util
import Vela
exposing
( AuthParams
, Build
, BuildNumber
, Builds
, ChownRepo
, CurrentUser
, Deployment
, DeploymentId
, EnableRepo
, EnableRepos
, EnableRepositoryPayload
, Enabling(..)
, Engine
, Event
, Favicon
, Field
, FocusFragment
, Hooks
, Key
, Log
, Logs
, Name
, Org
, PipelineModel
, PipelineTemplates
, Ref
, RepairRepo
, Repo
, RepoModel
, RepoResourceIdentifier
, RepoSearchFilters
, Repositories
, Repository
, Secret
, SecretType(..)
, Secrets
, ServiceNumber
, Services
, SourceRepositories
, StepNumber
, Steps
, Team
, Templates
, Theme(..)
, Type
, UpdateRepositoryPayload
, UpdateUserPayload
, buildUpdateFavoritesPayload
, buildUpdateRepoBoolPayload
, buildUpdateRepoIntPayload
, buildUpdateRepoStringPayload
, decodeTheme
, defaultEnableRepositoryPayload
, defaultFavicon
, defaultPipeline
, defaultPipelineTemplates
, defaultRepoModel
, encodeEnableRepository
, encodeTheme
, encodeUpdateRepository
, encodeUpdateUser
, isComplete
, secretTypeToString
, statusToFavicon
, stringToTheme
, updateBuild
, updateBuildNumber
, updateBuildPipelineBuildNumber
, updateBuildPipelineConfig
, updateBuildPipelineExpand
, updateBuildPipelineFocusFragment
, updateBuildPipelineLineFocus
, updateBuildPipelineOrgRepo
, updateBuildPipelineRef
, updateBuildServices
, updateBuildServicesFocusFragment
, updateBuildServicesFollowing
, updateBuildServicesLogs
, updateBuildSteps
, updateBuildStepsFocusFragment
, updateBuildStepsFollowing
, updateBuildStepsLogs
, updateBuilds
, updateBuildsEvent
, updateBuildsPage
, updateBuildsPager
, updateBuildsPerPage
, updateDeployments
, updateDeploymentsPage
, updateDeploymentsPager
, updateDeploymentsPerPage
, updateHooks
, updateHooksPage
, updateHooksPager
, updateHooksPerPage
, updateOrgRepo
, updateOrgReposPage
, updateOrgReposPager
, updateOrgReposPerPage
, updateOrgRepositories
, updateRepo
, updateRepoCounter
, updateRepoEnabling
, updateRepoInitialized
, updateRepoTimeout
)
-- TYPES
type alias Flags =
{ isDev : Bool
, velaAPI : String
, velaFeedbackURL : String
, velaDocsURL : String
, velaTheme : String
, velaRedirect : String
, velaLogBytesLimit : Int
}
type alias Model =
{ page : Page
, session : Session
, user : WebData CurrentUser
, toasties : Stack Alert
, sourceRepos : WebData SourceRepositories
, repo : RepoModel
, velaAPI : String
, velaFeedbackURL : String
, velaDocsURL : String
, velaRedirect : String
, velaLogBytesLimit : Int
, navigationKey : Navigation.Key
, zone : Zone
, time : Posix
, filters : RepoSearchFilters
, favoritesFilter : String
, entryURL : Url
, theme : Theme
, shift : Bool
, visibility : Visibility
, showHelp : Bool
, showIdentity : Bool
, favicon : Favicon
, secretsModel : Pages.Secrets.Model.Model Msg
, deploymentModel : Pages.Deployments.Model.Model Msg
, pipeline : PipelineModel
, templates : PipelineTemplates
, buildMenuOpen : List Int
}
type Interval
= OneSecond
| OneSecondHidden
| FiveSecond RefreshData
| FiveSecondHidden RefreshData
type alias RefreshData =
{ org : Org
, repo : Repo
, build_number : Maybe BuildNumber
, steps : Maybe Steps
}
init : Flags -> Url -> Navigation.Key -> ( Model, Cmd Msg )
init flags url navKey =
let
model : Model
model =
{ page = Pages.Overview
, session = Unauthenticated
, user = NotAsked
, sourceRepos = NotAsked
, velaAPI = flags.velaAPI
, velaFeedbackURL = flags.velaFeedbackURL
, velaDocsURL = flags.velaDocsURL
, velaRedirect = flags.velaRedirect
, velaLogBytesLimit = flags.velaLogBytesLimit
, navigationKey = navKey
, toasties = Alerting.initialState
, zone = utc
, time = millisToPosix 0
, filters = Dict.empty
, favoritesFilter = ""
, repo = defaultRepoModel
, entryURL = url
, theme = stringToTheme flags.velaTheme
, shift = False
, visibility = Visible
, showHelp = False
, showIdentity = False
, buildMenuOpen = []
, favicon = defaultFavicon
, secretsModel = initSecretsModel
, deploymentModel = initDeploymentsModel
, pipeline = defaultPipeline
, templates = defaultPipelineTemplates
}
( newModel, newPage ) =
setNewPage (Routes.match url) model
setTimeZone : Cmd Msg
setTimeZone =
Task.perform AdjustTimeZone here
setTime : Cmd Msg
setTime =
Task.perform AdjustTime Time.now
fetchToken : Cmd Msg
fetchToken =
case String.length model.velaRedirect of
0 ->
getToken model
_ ->
Cmd.none
in
( newModel
, Cmd.batch
[ fetchToken
, newPage
, Interop.setTheme <| encodeTheme model.theme
, setTimeZone
, setTime
]
)
-- UPDATE
type Msg
= -- User events
NewRoute Routes.Route
| ClickedLink UrlRequest
| SearchSourceRepos Org String
| SearchFavorites String
| ChangeRepoTimeout String
| ChangeRepoCounter String
| RefreshSettings Org Repo
| RefreshHooks Org Repo
| RefreshSecrets Engine SecretType Org Repo
| FilterBuildEventBy (Maybe Event) Org Repo
| SetTheme Theme
| GotoPage Pagination.Page
| ShowHideHelp (Maybe Bool)
| ShowHideBuildMenu Int (Maybe Bool)
| ShowHideIdentity (Maybe Bool)
| Copy String
| DownloadFile String (String -> String) String String
| ExpandAllSteps Org Repo BuildNumber
| CollapseAllSteps
| ExpandStep Org Repo BuildNumber StepNumber
| FollowStep Int
| ExpandAllServices Org Repo BuildNumber
| CollapseAllServices
| ExpandService Org Repo BuildNumber ServiceNumber
| FollowService Int
| ShowHideTemplates
| FocusPipelineConfigLineNumber Int
-- Outgoing HTTP requests
| RefreshAccessToken
| SignInRequested
| FetchSourceRepositories
| ToggleFavorite Org (Maybe Repo)
| EnableRepos Repositories
| EnableRepo Repository
| DisableRepo Repository
| ChownRepo Repository
| RepairRepo Repository
| UpdateRepoEvent Org Repo Field Bool
| UpdateRepoAccess Org Repo Field String
| UpdateRepoPipelineType Org Repo Field String
| UpdateRepoTimeout Org Repo Field Int
| UpdateRepoCounter Org Repo Field Int
| RestartBuild Org Repo BuildNumber
| CancelBuild Org Repo BuildNumber
| GetPipelineConfig Org Repo (Maybe BuildNumber) (Maybe Ref) FocusFragment Bool
| ExpandPipelineConfig Org Repo (Maybe BuildNumber) (Maybe Ref) FocusFragment Bool
-- Inbound HTTP responses
| LogoutResponse (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
| TokenResponse (Result (Http.Detailed.Error String) ( Http.Metadata, JwtAccessToken ))
| CurrentUserResponse (Result (Http.Detailed.Error String) ( Http.Metadata, CurrentUser ))
| SourceRepositoriesResponse (Result (Http.Detailed.Error String) ( Http.Metadata, SourceRepositories ))
| RepoFavoritedResponse String Bool (Result (Http.Detailed.Error String) ( Http.Metadata, CurrentUser ))
| RepoResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Repository ))
| OrgRepositoriesResponse (Result (Http.Detailed.Error String) ( Http.Metadata, List Repository ))
| RepoEnabledResponse Repository (Result (Http.Detailed.Error String) ( Http.Metadata, Repository ))
| RepoDisabledResponse Repository (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
| RepoUpdatedResponse Field (Result (Http.Detailed.Error String) ( Http.Metadata, Repository ))
| RepoChownedResponse Repository (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
| RepoRepairedResponse Repository (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
| RestartedBuildResponse Org Repo BuildNumber (Result (Http.Detailed.Error String) ( Http.Metadata, Build ))
| CancelBuildResponse Org Repo BuildNumber (Result (Http.Detailed.Error String) ( Http.Metadata, Build ))
| OrgBuildsResponse Org (Result (Http.Detailed.Error String) ( Http.Metadata, Builds ))
| BuildsResponse Org Repo (Result (Http.Detailed.Error String) ( Http.Metadata, Builds ))
| DeploymentsResponse Org Repo (Result (Http.Detailed.Error String) ( Http.Metadata, List Deployment ))
| HooksResponse Org Repo (Result (Http.Detailed.Error String) ( Http.Metadata, Hooks ))
| BuildResponse Org Repo BuildNumber (Result (Http.Detailed.Error String) ( Http.Metadata, Build ))
| DeploymentResponse Org Repo DeploymentId (Result (Http.Detailed.Error String) ( Http.Metadata, Deployment ))
| StepsResponse Org Repo BuildNumber FocusFragment Bool (Result (Http.Detailed.Error String) ( Http.Metadata, Steps ))
| StepLogResponse StepNumber FocusFragment Bool (Result (Http.Detailed.Error String) ( Http.Metadata, Log ))
| ServicesResponse Org Repo BuildNumber (Maybe String) Bool (Result (Http.Detailed.Error String) ( Http.Metadata, Services ))
| ServiceLogResponse ServiceNumber FocusFragment Bool (Result (Http.Detailed.Error String) ( Http.Metadata, Log ))
| GetPipelineConfigResponse Org Repo (Maybe Ref) FocusFragment Bool (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
| ExpandPipelineConfigResponse Org Repo (Maybe Ref) FocusFragment Bool (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
| GetPipelineTemplatesResponse Org Repo FocusFragment Bool (Result (Http.Detailed.Error String) ( Http.Metadata, Templates ))
| SecretResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Secret ))
| AddSecretResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Secret ))
| AddDeploymentResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Deployment ))
| UpdateSecretResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Secret ))
| RepoSecretsResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Secrets ))
| OrgSecretsResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Secrets ))
| SharedSecretsResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Secrets ))
| DeleteSecretResponse (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
-- Time
| AdjustTimeZone Zone
| AdjustTime Posix
| Tick Interval Posix
-- Components
| AddSecretUpdate Engine Pages.Secrets.Model.Msg
| AddDeploymentUpdate Pages.Deployments.Model.Msg
-- Other
| HandleError Error
| AlertsUpdate (Alerting.Msg Alert)
| FocusOn String
| FocusResult (Result Dom.Error ())
| OnKeyDown String
| OnKeyUp String
| VisibilityChanged Visibility
| PushUrl String
-- NoOp
| NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
let
rm =
model.repo
pipeline =
model.pipeline
in
case msg of
-- User events
NewRoute route ->
setNewPage route model
ClickedLink urlRequest ->
case urlRequest of
Browser.Internal url ->
( model, Navigation.pushUrl model.navigationKey <| Url.toString url )
Browser.External url ->
( model, Navigation.load url )
SearchSourceRepos org searchBy ->
let
filters =
Dict.update org (\_ -> Just searchBy) model.filters
in
( { model | filters = filters }, Cmd.none )
SearchFavorites searchBy ->
( { model | favoritesFilter = searchBy }, Cmd.none )
ChangeRepoTimeout timeout ->
let
newTimeout =
case String.toInt timeout of
Just t ->
Just t
Nothing ->
Just 0
in
( { model | repo = updateRepoTimeout newTimeout rm }, Cmd.none )
ChangeRepoCounter counter ->
let
newCounter =
case String.toInt counter of
Just t ->
Just t
Nothing ->
Just 0
in
( { model | repo = updateRepoCounter newCounter rm }, Cmd.none )
RefreshSettings org repo ->
( { model
| repo =
rm
|> updateRepoTimeout Nothing
|> updateRepoCounter Nothing
|> updateRepo Loading
}
, Api.try RepoResponse <| Api.getRepo model org repo
)
RefreshHooks org repo ->
( { model | repo = updateHooks Loading rm }, getHooks model org repo Nothing Nothing )
RefreshSecrets engine type_ org key ->
let
secretsModel =
model.secretsModel
in
case type_ of
Vela.RepoSecret ->
( { model | secretsModel = { secretsModel | repoSecrets = Loading } }
, getRepoSecrets model Nothing Nothing engine org key
)
Vela.OrgSecret ->
( { model | secretsModel = { secretsModel | orgSecrets = Loading } }
, getOrgSecrets model Nothing Nothing engine org
)
Vela.SharedSecret ->
( { model | secretsModel = { secretsModel | sharedSecrets = Loading } }
, getSharedSecrets model Nothing Nothing engine org key
)
FilterBuildEventBy maybeEvent org repo ->
let
route =
case repo of
"" ->
Routes.OrgBuilds org Nothing Nothing maybeEvent
_ ->
Routes.RepositoryBuilds org repo Nothing Nothing maybeEvent
in
( { model
| repo =
rm
|> updateBuilds Loading
|> updateBuildsPager []
}
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| route
)
SetTheme theme ->
if theme == model.theme then
( model, Cmd.none )
else
( { model | theme = theme }, Interop.setTheme <| encodeTheme theme )
GotoPage pageNumber ->
case model.page of
Pages.OrgBuilds org _ maybePerPage maybeEvent ->
( { model | repo = updateBuilds Loading rm }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.OrgBuilds org (Just pageNumber) maybePerPage maybeEvent
)
Pages.OrgRepositories org _ maybePerPage ->
( { model | repo = updateOrgRepositories Loading rm }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.OrgRepositories org (Just pageNumber) maybePerPage
)
Pages.RepositoryBuilds org repo _ maybePerPage maybeEvent ->
( { model | repo = updateBuilds Loading rm }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.RepositoryBuilds org repo (Just pageNumber) maybePerPage maybeEvent
)
Pages.RepositoryDeployments org repo _ maybePerPage ->
( { model | repo = updateDeployments Loading rm }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.RepositoryDeployments org repo (Just pageNumber) maybePerPage
)
Pages.Hooks org repo _ maybePerPage ->
( { model | repo = updateHooks Loading rm }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.Hooks org repo (Just pageNumber) maybePerPage
)
Pages.RepoSecrets engine org repo _ maybePerPage ->
let
currentSecrets =
model.secretsModel
loadingSecrets =
{ currentSecrets | repoSecrets = Loading }
in
( { model | secretsModel = loadingSecrets }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.RepoSecrets engine org repo (Just pageNumber) maybePerPage
)
Pages.OrgSecrets engine org _ maybePerPage ->
let
currentSecrets =
model.secretsModel
loadingSecrets =
{ currentSecrets | orgSecrets = Loading }
in
( { model | secretsModel = loadingSecrets }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.OrgSecrets engine org (Just pageNumber) maybePerPage
)
Pages.SharedSecrets engine org team _ maybePerPage ->
let
currentSecrets =
model.secretsModel
loadingSecrets =
{ currentSecrets | sharedSecrets = Loading }
in
( { model | secretsModel = loadingSecrets }
, Navigation.pushUrl model.navigationKey <| Routes.routeToUrl <| Routes.SharedSecrets engine org team (Just pageNumber) maybePerPage
)
_ ->
( model, Cmd.none )
ShowHideHelp show ->
( { model
| showHelp =
case show of
Just s ->
s
Nothing ->
not model.showHelp
}
, Cmd.none
)
ShowHideBuildMenu build show ->
let
buildsOpen =
model.buildMenuOpen
replaceList : Int -> List Int -> List Int
replaceList id buildList =
if List.member id buildList then
[]
else
[ id ]
updatedOpen : List Int
updatedOpen =
case show of
Just _ ->
buildsOpen
Nothing ->
replaceList build buildsOpen
in
( { model
| buildMenuOpen = updatedOpen
}
, Cmd.none
)
ShowHideIdentity show ->
( { model
| showIdentity =
case show of
Just s ->
s
Nothing ->
not model.showIdentity
}
, Cmd.none
)
Copy content ->
( model, Cmd.none )
|> Alerting.addToast Alerts.successConfig
AlertsUpdate
(Alerts.Success ""
("Copied " ++ wrapAlertMessage content ++ "to your clipboard.")
Nothing
)
DownloadFile ext fn filename content ->
( model
, Download.string filename ext <| fn content
)
-- steps
ExpandAllSteps org repo buildNumber ->
let
build =
rm.build
steps =
RemoteData.unwrap build.steps.steps
(\steps_ -> steps_ |> setAllViews True |> RemoteData.succeed)
build.steps.steps
-- refresh logs for expanded steps
action =
getBuildStepsLogs model org repo buildNumber (RemoteData.withDefault [] steps) Nothing True
in
( { model | repo = updateBuildSteps steps rm }
, action
)
CollapseAllSteps ->
let
build =
rm.build
steps =
build.steps.steps
|> RemoteData.unwrap build.steps.steps
(\steps_ -> steps_ |> setAllViews False |> RemoteData.succeed)
in
( { model | repo = rm |> updateBuildSteps steps |> updateBuildStepsFollowing 0 }
, Cmd.none
)
ExpandStep org repo buildNumber stepNumber ->
let
build =
rm.build
( steps, fetchStepLogs ) =
clickResource build.steps.steps stepNumber
action =
if fetchStepLogs then
getBuildStepLogs model org repo buildNumber stepNumber Nothing True
else
Cmd.none
stepOpened =
isViewing steps stepNumber
-- step clicked is step being followed
onFollowedStep =
build.steps.followingStep == (Maybe.withDefault -1 <| String.toInt stepNumber)
follow =
if onFollowedStep && not stepOpened then
-- stop following a step when collapsed
0
else
build.steps.followingStep
in
( { model | repo = rm |> updateBuildSteps steps |> updateBuildStepsFollowing follow }
, Cmd.batch <|
[ action
, if stepOpened then
Navigation.pushUrl model.navigationKey <| resourceFocusFragment "step" stepNumber []
else
Cmd.none
]
)
FollowStep follow ->
( { model | repo = updateBuildStepsFollowing follow rm }
, Cmd.none
)
-- services
ExpandAllServices org repo buildNumber ->
let
build =
rm.build
services =
RemoteData.unwrap build.services.services
(\services_ -> services_ |> setAllViews True |> RemoteData.succeed)
build.services.services
-- refresh logs for expanded services
action =
getBuildServicesLogs model org repo buildNumber (RemoteData.withDefault [] services) Nothing True
in
( { model | repo = updateBuildServices services rm }
, action
)
CollapseAllServices ->
let
build =
rm.build
services =
build.services.services
|> RemoteData.unwrap build.services.services
(\services_ -> services_ |> setAllViews False |> RemoteData.succeed)
in
( { model | repo = rm |> updateBuildServices services |> updateBuildServicesFollowing 0 }
, Cmd.none
)
ExpandService org repo buildNumber serviceNumber ->
let
build =
rm.build
( services, fetchServiceLogs ) =
clickResource build.services.services serviceNumber
action =
if fetchServiceLogs then
getBuildServiceLogs model org repo buildNumber serviceNumber Nothing True
else
Cmd.none
serviceOpened =
isViewing services serviceNumber
-- step clicked is service being followed
onFollowedService =
build.services.followingService == (Maybe.withDefault -1 <| String.toInt serviceNumber)
follow =
if onFollowedService && not serviceOpened then
-- stop following a service when collapsed
0
else
build.services.followingService
in
( { model | repo = rm |> updateBuildServices services |> updateBuildServicesFollowing follow }
, Cmd.batch <|
[ action
, if serviceOpened then
Navigation.pushUrl model.navigationKey <| resourceFocusFragment "service" serviceNumber []
else
Cmd.none
]
)
FollowService follow ->
( { model | repo = updateBuildServicesFollowing follow rm }
, Cmd.none
)
ShowHideTemplates ->
let
templates =
model.templates
in
( { model | templates = { templates | show = not templates.show } }, Cmd.none )
FocusPipelineConfigLineNumber line ->
let
url =
lineRangeId "config" "0" line pipeline.lineFocus model.shift
in
( { model
| pipeline =
{ pipeline
| lineFocus = pipeline.lineFocus
}
}
, Navigation.pushUrl model.navigationKey <| url
)
-- Outgoing HTTP requests
RefreshAccessToken ->
( model, getToken model )
SignInRequested ->
-- Login on server needs to accept redirect URL and pass it along to as part of 'state' encoded as base64
-- so we can parse it when the source provider redirects back to the API
( model, Navigation.load <| Api.Endpoint.toUrl model.velaAPI Api.Endpoint.Login )
FetchSourceRepositories ->
( { model | sourceRepos = Loading, filters = Dict.empty }, Api.try SourceRepositoriesResponse <| Api.getSourceRepositories model )
ToggleFavorite org repo ->
let
favorite =
toFavorite org repo
( favorites, favorited ) =
updateFavorites model.user favorite
payload : UpdateUserPayload
payload =
buildUpdateFavoritesPayload favorites
body : Http.Body
body =
Http.jsonBody <| encodeUpdateUser payload
in
( model
, Api.try (RepoFavoritedResponse favorite favorited) (Api.updateCurrentUser model body)
)
EnableRepos repos ->
( model
, Cmd.batch <| List.map (Util.dispatch << EnableRepo) repos
)
EnableRepo repo ->
let
payload : EnableRepositoryPayload
payload =
buildEnableRepositoryPayload repo
body : Http.Body
body =
Http.jsonBody <| encodeEnableRepository payload
in
( { model
| sourceRepos = enableUpdate repo Loading model.sourceRepos
, repo = updateRepoEnabling Vela.Enabling rm
}
, Api.try (RepoEnabledResponse repo) <| Api.enableRepository model body
)
DisableRepo repo ->
let
( status, action ) =
case repo.enabling of
Vela.Enabled ->
( Vela.ConfirmDisable, Cmd.none )
Vela.ConfirmDisable ->
( Vela.Disabling, Api.try (RepoDisabledResponse repo) <| Api.deleteRepo model repo )
_ ->
( repo.enabling, Cmd.none )
in
( { model
| repo = updateRepoEnabling status rm
}
, action
)
ChownRepo repo ->
( model, Api.try (RepoChownedResponse repo) <| Api.chownRepo model repo )
RepairRepo repo ->
( model, Api.try (RepoRepairedResponse repo) <| Api.repairRepo model repo )
UpdateRepoEvent org repo field value ->
let
payload : UpdateRepositoryPayload
payload =
buildUpdateRepoBoolPayload field value
body : Http.Body
body =
Http.jsonBody <| encodeUpdateRepository payload
cmd =
if Pages.RepoSettings.validEventsUpdate rm.repo payload then
Api.try (RepoUpdatedResponse field) (Api.updateRepository model org repo body)
else
addErrorString "Could not disable webhook event. At least one event must be active." HandleError
in
( model
, cmd
)
UpdateRepoAccess org repo field value ->