22< html xmlns:th ="http://www.thymeleaf.org " class ="dark " data-bs-theme ="dark ">
33< head >
44 < meta th:replace ="~{fragments/header} ">
5- < title > [[${systemOptions.systemLogoName}]] - Add Integrations </ title >
5+ < title > [[${systemOptions.systemLogoName}]] - Add OpenAI Integration </ title >
66
77 < style >
8- .grid {
9- display : grid;
10- gap : 1.5rem ;
8+ .integration-form {
9+ max-width : 600px ;
10+ margin : 2rem auto;
11+ background : var (--bs-dark );
12+ border : 1px solid # 404040 ;
13+ border-radius : 12px ;
14+ padding : 2rem ;
1115 }
1216
13- .sm\\ : grid-cols-2 {
14- grid-template-columns : repeat (2 , minmax (0 , 1fr ));
17+ .integration-header {
18+ text-align : center;
19+ margin-bottom : 2rem ;
1520 }
1621
17- .lg\\ : grid-cols-3 {
18- grid-template-columns : repeat (3 , minmax (0 , 1fr ));
22+ .integration-icon {
23+ font-size : 3rem ;
24+ color : # 0d6efd ;
25+ margin-bottom : 1rem ;
1926 }
2027
21- .xl\\ : grid-cols-4 {
22- grid-template-columns : repeat ( 4 , minmax ( 0 , 1 fr )) ;
28+ .form-group {
29+ margin-bottom : 1.5 rem ;
2330 }
2431
25- .card {
26- border : 1px solid # ddd ;
27- border-radius : 8px ;
28- padding : 1rem ;
29- transition : background-color 0.2s ;
30- text-decoration : none;
31- color : inherit;
32+ .form-label {
33+ font-weight : 600 ;
34+ margin-bottom : 0.5rem ;
35+ color : # fff ;
3236 }
3337
34- .card : hover {
35- background-color : # f9f9f9 ;
38+ .form-control {
39+ background : var (--bs-dark );
40+ border : 1px solid # 404040 ;
41+ color : # fff ;
3642 }
3743
38- .card-header {
39- display : flex;
40- justify-content : space-between;
41- align-items : center;
44+ .form-control : focus {
45+ background : var (--bs-dark );
46+ border-color : # 0d6efd ;
47+ color : # fff ;
48+ box-shadow : 0 0 0 0.2rem rgba (13 , 110 , 253 , 0.25 );
4249 }
4350
44- .card-title {
45- font-size : 1rem ;
46- font-weight : 500 ;
51+ .btn-primary {
52+ background : linear-gradient (135deg , # 0d6efd, # 6610f2 );
53+ border : none;
54+ padding : 0.75rem 2rem ;
55+ font-weight : 600 ;
4756 }
4857
49- .card-description {
50- font-size : 0.875rem ;
51- color : # 666 ;
58+ .btn-secondary {
59+ background : transparent;
60+ border : 1px solid # 404040 ;
61+ color : # adb5bd ;
5262 }
5363
54- .icon {
55- font-size : 1.25rem ;
56- color : # 888 ;
64+ .help-text {
65+ font-size : 0.875rem ;
66+ color : # adb5bd ;
67+ margin-top : 0.25rem ;
5768 }
5869 </ style >
5970
6576 const formData = new FormData ( form ) ;
6677 const jsonData = Object . fromEntries ( formData . entries ( ) ) ;
6778 var csrf = "[[${_csrf.token}]]"
79+
80+ // Show loading state
81+ const submitBtn = form . querySelector ( 'button[type="submit"]' ) ;
82+ const originalText = submitBtn . innerHTML ;
83+ submitBtn . disabled = true ;
84+ submitBtn . innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Connecting...' ;
85+
6886 try {
6987 const response = await fetch ( form . action , {
7088 method : "POST" ,
7694 } ) ;
7795
7896 if ( response . ok ) {
79- const redirectUrl = "/sso/v1/integrations" ; // Modify as needed
80- window . location . href = redirectUrl ;
97+ submitBtn . innerHTML = '<i class="fas fa-check me-2"></i>Connected!' ;
98+ setTimeout ( ( ) => {
99+ const redirectUrl = "/sso/v1/integrations" ;
100+ window . location . href = redirectUrl ;
101+ } , 1000 ) ;
81102 } else {
82- const errorText = await response . text ( ) ;
83- alert ( "Error: " + errorText ) ;
103+ throw new Error ( "Failed to create integration" ) ;
84104 }
85105 } catch ( error ) {
86- console . error ( "Request failed" , error ) ;
87- alert ( "Failed to save integration." ) ;
106+ submitBtn . disabled = false ;
107+ submitBtn . innerHTML = originalText ;
108+ console . error ( "Error:" , error ) ;
109+ alert ( "An error occurred while creating the integration." ) ;
88110 }
89111 }
90112 </ script >
97119 < div class ="col py-4 ">
98120 < div class ="main-content ">
99121 < div th:replace ="~{fragments/alerts} "> </ div >
100- < div class ="container ">
101- < h1 > Set Up OpenAI Integration</ h1 >
102- < form th:action ="@{/api/v1/integrations/openai/add} " th:object ="${openaiIntegration} " method ="post " onsubmit ="submitIntegration(event) ">
122+
123+ < div class ="integration-form ">
124+ < div class ="integration-header ">
125+ < i class ="fa-solid fa-robot integration-icon "> </ i >
126+ < h1 > Connect OpenAI</ h1 >
127+ < p class ="text-muted "> Integrate AI capabilities and natural language processing into your workflows.</ p >
128+ </ div >
103129
130+ < form th:action ="@{/api/v1/integrations/openai/add} " th:object ="${openaiIntegration} " method ="post " onsubmit ="submitIntegration(event) ">
104131 < div class ="form-group ">
105- < label for ="name "> Integration Name</ label >
132+ < label for ="name " class =" form-label " > Integration Name</ label >
106133 < input type ="text " id ="name " name ="name " class ="form-control "
107- th:field ="*{name} " placeholder ="Enter your Integration Name " required >
134+ th:field ="*{name} " placeholder ="My OpenAI Integration " required >
135+ < div class ="help-text "> Choose a name to identify this integration</ div >
108136 </ div >
109137
110138 < div class ="form-group ">
111- < label for ="username "> OpenAI Principal </ label >
139+ < label for ="username " class =" form-label " > OpenAI Organization ID </ label >
112140 < input type ="text " id ="username " name ="username " class ="form-control "
113- th:field ="*{username} " placeholder ="Enter your Jira username " required >
141+ th:field ="*{username} " placeholder ="org-xxxxxxxxx (optional) ">
142+ < div class ="help-text "> Your OpenAI organization ID (optional for personal accounts)</ div >
114143 </ div >
115144
116145 < div class ="form-group ">
117- < label for ="apiToken "> Open AI Token </ label >
146+ < label for ="apiToken " class =" form-label " > OpenAI API Key </ label >
118147 < input type ="password " id ="apiToken " name ="apiToken " class ="form-control "
119- th:field ="*{apiToken} " placeholder ="Enter your Jira API token " required >
148+ th:field ="*{apiToken} " placeholder ="sk-xxxxxxxxx " required >
149+ < div class ="help-text ">
150+ < i class ="fas fa-info-circle me-1 "> </ i >
151+ Generate an API key at < a href ="https://platform.openai.com/api-keys " target ="_blank " class ="text-primary "> OpenAI Platform</ a >
152+ </ div >
120153 </ div >
121154
122- < div class ="form-actions ">
123- < button type ="submit " class ="btn btn-primary "> Save Integration</ button >
155+ < div class ="form-group ">
156+ < label for ="baseUrl " class ="form-label "> API Base URL</ label >
157+ < input type ="text " id ="baseUrl " name ="baseUrl " class ="form-control "
158+ th:field ="*{baseUrl} " placeholder ="https://api.openai.com/v1 " value ="https://api.openai.com/v1 ">
159+ < div class ="help-text "> Use default URL unless you're using a custom endpoint</ div >
124160 </ div >
161+
162+ < div class ="d-flex gap-2 justify-content-end ">
163+ < a href ="/sso/v1/integrations " class ="btn btn-secondary "> Cancel</ a >
164+ < button type ="submit " class ="btn btn-primary ">
165+ < i class ="fas fa-plug me-2 "> </ i > Connect OpenAI
166+ </ button >
167+ </ div >
168+
169+ < input type ="hidden " name ="_csrf " th:value ="${_csrf.token} "/>
125170 </ form >
126171 </ div >
172+
127173 </ div >
128174 </ div >
129175 </ div >
130176</ div >
131177
132178</ body >
133- </ html >
179+ </ html >
0 commit comments