1
- import { createContext , Fragment , render , VNode } from "preact" ;
1
+ import { Fragment , render , VNode } from "preact" ;
2
2
import { Modal } from "js/toolbox" ;
3
3
import { useContext , useEffect , useReducer , useState } from "preact/hooks" ;
4
4
import * as toolbox from "js/toolbox" ;
5
5
import _ from "lodash" ;
6
6
import { ChangeEvent } from "react-dom/src" ;
7
7
import styled from "styled-components" ;
8
+ import { Config , AppConfig , RawConfig } from "./config" ;
9
+ import { AddPeopleState , AvailableProviderTypes , Collaborator , PeopleStateReducer , Person , PersonState , UserProvider } from "./types" ;
8
10
9
11
export default function ( {
10
12
dom,
11
13
config : jsonConfig ,
12
14
} : {
13
15
dom : HTMLElement ;
14
- config : any ;
16
+ config : RawConfig ;
15
17
} ) {
16
18
render (
17
- < Config . Provider value = { State . fromJSON ( jsonConfig as DOMStringMap ) } >
19
+ < Config . Provider value = { AppConfig . fromJSON ( jsonConfig ) } >
18
20
< App />
19
21
</ Config . Provider > ,
20
22
dom
@@ -63,6 +65,7 @@ const AddNewUsers = (props: { close: (reload: boolean) => void, }) => {
63
65
64
66
const [ loading , setLoading ] = useState ( true ) ;
65
67
68
+
66
69
useEffect ( ( ) => {
67
70
void config . collaboratorListUrl
68
71
. call ( )
@@ -140,7 +143,7 @@ const AddNewUsers = (props: { close: (reload: boolean) => void, }) => {
140
143
</ div >
141
144
142
145
{ userProviders . length > 1 && (
143
- < div className = "mb3 button-group ph4 w-100" >
146
+ < div className = "mb3 button-group ph4 w-100 items-center justify-center " >
144
147
{ userProviders . map ( userProviderBox ) }
145
148
</ div >
146
149
) }
@@ -193,9 +196,8 @@ const ProvideVia = (props: ProvideViaProps) => {
193
196
( collaborator ) => collaborator . provider === props . provider . toLowerCase ( )
194
197
)
195
198
) ;
196
- const [ selectedCollaborators , setSelectedCollaborators ] = useState <
197
- Collaborator [ ]
198
- > ( [ ] ) ;
199
+
200
+ const [ selectedCollaborators , setSelectedCollaborators ] = useState < Collaborator [ ] > ( [ ] ) ;
199
201
200
202
const toggleCollaborator = ( collaborator : Collaborator ) => {
201
203
if ( selectedCollaborators . includes ( collaborator ) ) {
@@ -621,62 +623,6 @@ const ProvideViaEmail = (props: ProvideViaEmailProps) => {
621
623
) ;
622
624
} ;
623
625
624
- export class State {
625
- collaboratorListUrl : toolbox . APIRequest . Url < { collaborators : any , } > ;
626
- inviteMemberUrl : toolbox . APIRequest . Url < { message : string , } > ;
627
- createMemberUrl : toolbox . APIRequest . Url < {
628
- password : string ;
629
- message : string ;
630
- } > ;
631
- allowedProviders : UserProvider [ ] = [ ] ;
632
-
633
- static fromJSON ( rawJson : DOMStringMap ) : State {
634
- const config = State . default ( ) ;
635
- const json = JSON . parse ( rawJson . config ) ;
636
-
637
- config . collaboratorListUrl = toolbox . APIRequest . Url . fromJSON (
638
- json . users . collaborators_url
639
- ) ;
640
- config . createMemberUrl = toolbox . APIRequest . Url . fromJSON (
641
- json . users . create_url
642
- ) ;
643
- config . inviteMemberUrl = toolbox . APIRequest . Url . fromJSON (
644
- json . users . invite_url
645
- ) ;
646
-
647
- json . users . providers
648
- . map ( ( provider : string ) => {
649
- switch ( provider ) {
650
- case `email` :
651
- return config . allowedProviders . push ( UserProvider . Email ) ;
652
- case `github` :
653
- return config . allowedProviders . push ( UserProvider . GitHub ) ;
654
- case `bitbucket` :
655
- return config . allowedProviders . push ( UserProvider . Bitbucket ) ;
656
- case `gitlab` :
657
- return config . allowedProviders . push ( UserProvider . GitLab ) ;
658
- default :
659
- return null ;
660
- }
661
- } )
662
- . filter ( ( provider : UserProvider | null ) => provider ) ;
663
- return config ;
664
- }
665
-
666
- static default ( ) : State {
667
- const config = new State ( ) ;
668
- return config ;
669
- }
670
- }
671
-
672
- export const Config = createContext < State > ( new State ( ) ) ;
673
-
674
- enum UserProvider {
675
- Email = `email` ,
676
- GitHub = `github` ,
677
- Bitbucket = `bitbucket` ,
678
- GitLab = `gitlab` ,
679
- }
680
626
681
627
const ActiveShadowLink = styled . button `
682
628
&:hover,
@@ -686,138 +632,10 @@ const ActiveShadowLink = styled.button`
686
632
}
687
633
` ;
688
634
689
- class Collaborator {
690
- displayName : string ;
691
- uid : string ;
692
- login : string ;
693
- provider : string ;
694
- avatarUrl : string ;
695
-
696
- constructor ( ) {
697
- this . displayName = `` ;
698
- this . uid = `` ;
699
- this . login = `` ;
700
- this . provider = `` ;
701
- this . avatarUrl = `` ;
702
- }
703
-
704
- static fromJSON ( json : any ) : Collaborator {
705
- const collaborator = new Collaborator ( ) ;
706
- collaborator . displayName = json . display_name as string ;
707
- collaborator . login = json . login as string ;
708
- collaborator . uid = json . uid as string ;
709
- collaborator . provider = json . provider as string ;
710
- collaborator . avatarUrl = json . avatar_url as string ;
711
-
712
- return collaborator ;
713
- }
714
-
715
- hasAvatar ( ) : boolean {
716
- return this . avatarUrl . length != 0 ;
717
- }
718
- }
719
-
720
- enum PersonState {
721
- Empty ,
722
- Loading ,
723
- Invited ,
724
- Error ,
725
- }
726
-
727
- class Person {
728
- id : string ;
729
- email : string ;
730
- username : string ;
731
- password = `` ;
732
- errorMessage = `` ;
733
- state : PersonState = PersonState . Empty ;
734
- wasInvited : boolean ;
735
- emailValid = true ;
736
-
737
- constructor ( ) {
738
- this . id = _ . uniqueId ( `person_` ) ;
739
- this . email = `` ;
740
- this . username = `` ;
741
- this . wasInvited = false ;
742
- }
743
-
744
- isEmpty ( ) : boolean {
745
- return _ . isEmpty ( this . email ) && _ . isEmpty ( this . username ) ;
746
- }
747
-
748
- init ( ) {
749
- this . password = `` ;
750
- this . errorMessage = `` ;
751
- this . state = PersonState . Empty ;
752
- }
753
-
754
- setPassword ( password : string ) {
755
- this . state = PersonState . Invited ;
756
- this . password = password ;
757
- }
758
-
759
- setError ( errorMessage : string ) {
760
- this . state = PersonState . Error ;
761
- this . errorMessage = errorMessage ;
762
- }
763
- setLoading ( ) {
764
- this . wasInvited = true ;
765
- this . state = PersonState . Loading ;
766
- }
767
- }
768
-
769
- class AddPeopleState {
770
- people : Person [ ] = [ new Person ( ) ] ;
771
- type : UserProvider ;
772
- }
773
-
774
- export type AddPeopleAction =
775
- | { type : `UPDATE_PERSON`, id : string , value : Person , }
776
- | { type : `REMOVE_PERSON`, id : string , }
777
- | { type : `RESET`, } ;
778
-
779
- const PeopleStateReducer = ( state : AddPeopleState , action : AddPeopleAction ) => {
780
- switch ( action . type ) {
781
- case `UPDATE_PERSON` : {
782
- const newPeople = state . people
783
- . map ( ( person ) => {
784
- if ( person . id == action . id ) {
785
- return action . value ;
786
- }
787
- return person ;
788
- } )
789
- . filter ( ( person ) => ! person . isEmpty ( ) ) ;
790
-
791
- newPeople . push ( new Person ( ) ) ;
792
-
793
- return { ...state , people : newPeople } ;
794
- }
795
-
796
- case `REMOVE_PERSON` : {
797
- const newPeople = state . people . filter ( ( person ) => person . id != action . id ) ;
798
-
799
- return { ...state , people : newPeople } ;
800
- }
801
-
802
- case `RESET` : {
803
- return { ...state , people : [ new Person ( ) ] } ;
804
- }
805
-
806
- default :
807
- return state ;
808
- }
809
- } ;
810
-
811
635
const ActiveShadowDiv = styled . div `
812
636
&:hover,
813
637
&.active {
814
638
z-index: 2;
815
639
box-shadow: 0 0 0 3px #00359f !important;
816
640
}
817
641
` ;
818
- const AvailableProviderTypes : UserProvider [ ] = [
819
- UserProvider . Email ,
820
- UserProvider . GitHub ,
821
- UserProvider . Bitbucket ,
822
- UserProvider . GitLab ,
823
- ] ;
0 commit comments