@@ -7,6 +7,7 @@ import UserProfileDisplay from './components/UserProfileDisplay.vue'
77import ApiKeyManager from ' ./components/ApiKeyManager.vue'
88import ScanJobList from ' ./components/ScanJobList.vue'
99import ScanConfigurationManager from ' ./components/ScanConfigurationManager.vue'
10+ import ProjectList from ' ./components/ProjectList.vue'
1011import axios from ' axios' ;
1112
1213const AUTH_API_URL = ' /api/v1/auth' ;
@@ -21,12 +22,14 @@ export default {
2122 UserProfileDisplay,
2223 ApiKeyManager,
2324 ScanJobList,
24- ScanConfigurationManager
25+ ScanConfigurationManager,
26+ ProjectList
2527 },
2628 data () {
2729 return {
2830 isLoggedIn: false ,
2931 currentProjectIdForConfigManager: null ,
32+ projectsForScanRunner: [],
3033 };
3134 },
3235 created () {
@@ -43,6 +46,9 @@ export default {
4346 axios .defaults .headers .common [' Authorization' ] = ` Token ${ token} ` ;
4447 this .isLoggedIn = true ;
4548 this .currentProjectIdForConfigManager = null ;
49+ if (this .$refs .projectList ) {
50+ this .$refs .projectList .fetchProjects ();
51+ }
4652 } else {
4753 console .error (" Login event received, but no token found in localStorage." );
4854 this .handleLogout (true );
@@ -65,34 +71,21 @@ export default {
6571 delete axios .defaults .headers .common [' Authorization' ];
6672 this .isLoggedIn = false ;
6773 this .currentProjectIdForConfigManager = null ;
74+ this .projectsForScanRunner = [];
6875 },
6976 handleSessionExpired () {
7077 this .handleLogout (true );
7178 },
7279 handleProjectSelectedForConfigManager (projectId ) {
7380 this .currentProjectIdForConfigManager = projectId;
7481 },
75- async createDefaultProject () {
76- try {
77- const response = await axios .post (' /api/v1/core/projects/' , { name: ' Default Project' });
78- console .log (' Default project created:' , response .data );
79- alert (' Default Project created successfully! The project list will refresh.' );
80- // Refresh the project list in ScanRunner, assuming ScanRunner component has a ref and a method to fetch projects
81- if (this .$refs .scanRunner && typeof this .$refs .scanRunner .fetchProjects === ' function' ) {
82- this .$refs .scanRunner .fetchProjects ();
83- } else {
84- console .warn (' ScanRunner component or fetchProjects method not available.' );
85- // Optionally, emit an event that a parent component or global state manager can listen to
86- // this.$root.$emit('projectListShouldRefresh'); // Example if using root instance as event bus
87- }
88- } catch (error) {
89- console .error (' Failed to create default project:' , error);
90- if (error .response && error .response .data && error .response .data .name && error .response .data .name [0 ].includes (' project with this name already exists' )) {
91- alert (' Failed to create default project: A project with the name "Default Project" already exists.' );
92- } else {
93- alert (' Failed to create default project: Request failed with status code ' + (error .response ? error .response .status : ' unknown' ));
94- }
95- }
82+ handleProjectListUpdate (updatedProjects ) {
83+ this .projectsForScanRunner = updatedProjects;
84+ console .log (' App.vue: projectsForScanRunner updated by ProjectList event:' , JSON .parse (JSON .stringify (updatedProjects)));
85+ },
86+ updateCurrentUser () {
87+ const token = localStorage .getItem (' authToken' );
88+ // ... existing code ...
9689 }
9790 }
9891}
@@ -119,11 +112,13 @@ export default {
119112 <hr class =" separator" />
120113 <ApiKeyManager :isLoggedIn =" isLoggedIn" @session-expired =" handleSessionExpired" />
121114 <hr class =" separator" />
115+ <ProjectList @project-list-updated =" handleProjectListUpdate" ref =" projectList" />
116+ <hr class =" separator" />
122117 <h2 >Scan Operations</h2 >
123- <button @click =" createDefaultProject" class =" action-button create-button" >Create Default Project</button >
124118 <ScanRunner
125119 ref =" scanRunner"
126120 :isLoggedIn =" isLoggedIn"
121+ :projects =" projectsForScanRunner"
127122 @session-expired =" handleSessionExpired"
128123 @project-selected =" handleProjectSelectedForConfigManager"
129124 />
@@ -142,69 +137,11 @@ export default {
142137 </div >
143138</template >
144139
145- <style >
146- #app {
147- font-family : Avenir, Helvetica , Arial , sans-serif ;
148- -webkit-font-smoothing : antialiased ;
149- -moz-osx-font-smoothing : grayscale ;
150- color : #2c3e50 ;
151- margin-top : 60px ;
152- }
153-
154- header {
155- text-align : center ;
156- margin-bottom : 40px ;
157- position : relative ;
158- }
159-
160- header img {
161- width : 80px ;
162- height : 80px ;
163- }
164-
165- .user-status {
166- position : absolute ;
167- top : 10px ;
168- right : 20px ;
169- display : flex ;
170- align-items : center ;
171- font-size : 0.9em ;
172- }
173-
174- .user-status span {
175- margin-right : 10px ;
176- }
177-
178- .user-status button {
179- padding : 5px 10px ;
180- background-color : #dc3545 ;
181- color : white ;
182- border : none ;
183- border-radius : 4px ;
184- cursor : pointer ;
185- }
186-
187- main {
188- max-width : 900px ;
189- margin : 0 auto ;
190- padding : 20px ;
191- }
192-
193- .auth-section ,
194- .main-content {
195- padding : 20px ;
196- border : 1px solid #e0e0e0 ;
197- border-radius : 8px ;
198- background-color : #f9f9f9 ;
199- }
200-
201- .separator {
202- margin : 40px 0 ;
203- border : 0 ;
204- border-top : 1px solid #e9ecef ;
205- }
206-
207- main h2 {
208- text-align : center ;
140+ <style scoped>
141+ /* If App.vue has any specific scoped styles, they would remain here. */
142+ /* For example, if #app itself needed very specific App.vue-only styling */
143+ /* Based on current structure, likely no scoped styles needed here. */
144+ .app-container {
145+ /* Example if needed */
209146}
210147 </style >
0 commit comments