1- import { ChangeDetectionStrategy , Component , inject , signal , ElementRef , ViewChild } from '@angular/core' ;
1+ import { ChangeDetectionStrategy , Component , inject , signal , ElementRef , ViewChild , effect } from '@angular/core' ;
22import { Router } from '@angular/router' ;
33import { FileSystemService } from '../../services/file-system.service' ;
44import { DataStateService } from '../../services/data-state.service' ;
55import { SvgIconComponent } from "angular-svg-icon" ;
6+ import { GithubRepoService } from '../../services/github-repo.service' ;
67
78type DropZone = 'folder' | 'obo' | 'diaf' | 'metadata' ;
89
@@ -16,6 +17,7 @@ type DropZone = 'folder' | 'obo' | 'diaf' | 'metadata';
1617export class FileSelectorComponent {
1718 private fileSystemService = inject ( FileSystemService ) ;
1819 private dataStateService = inject ( DataStateService ) ;
20+ private githubRepoService = inject ( GithubRepoService ) ;
1921 private router = inject ( Router ) ;
2022
2123 @ViewChild ( 'folderInput' ) folderInput ! : ElementRef < HTMLInputElement > ;
@@ -24,6 +26,21 @@ export class FileSelectorComponent {
2426 protected readonly supportsFileSystemAccess = this . fileSystemService . supportsFileSystemAccess ;
2527 protected readonly isLoading = signal ( false ) ;
2628 protected readonly error = signal < string | null > ( null ) ;
29+ protected readonly githubError = signal < string | null > ( null ) ;
30+ protected readonly isGithubLoading = signal ( false ) ;
31+ protected readonly githubStatus = this . githubRepoService . statusMessage ;
32+
33+ protected readonly githubRepo = signal ( 'pegi3s/dockerfiles' ) ;
34+ protected readonly githubBranch = signal ( 'master' ) ;
35+ protected readonly githubToken = signal ( '' ) ;
36+ protected readonly githubAuthorName = signal ( '' ) ;
37+ protected readonly githubAuthorEmail = signal ( '' ) ;
38+
39+ private readonly storageKeys = {
40+ githubToken : 'bdip.github.token' ,
41+ githubAuthorName : 'bdip.github.authorName' ,
42+ githubAuthorEmail : 'bdip.github.authorEmail' ,
43+ } as const ;
2744
2845 // Individual drag states
2946 protected readonly isDragOverFolder = signal ( false ) ;
@@ -48,6 +65,134 @@ export class FileSelectorComponent {
4865 protected readonly currentFileAccept = signal ( '.json,.obo,.diaf' ) ;
4966 private currentFileType : 'obo' | 'diaf' | 'metadata' = 'metadata' ;
5067
68+ constructor ( ) {
69+ this . restoreGithubPrefs ( ) ;
70+ this . setupGithubPersistence ( ) ;
71+ }
72+
73+ async onLoadFromGithub ( ) : Promise < void > {
74+ this . githubError . set ( null ) ;
75+ this . isGithubLoading . set ( true ) ;
76+
77+ try {
78+ this . githubRepoService . setToken ( this . githubToken ( ) ) ;
79+ this . githubRepoService . setAuthor (
80+ this . githubAuthorName ( ) ,
81+ this . githubAuthorEmail ( )
82+ ) ;
83+ const result = await this . githubRepoService . connectAndLoad (
84+ this . githubRepo ( ) ,
85+ this . githubBranch ( )
86+ ) ;
87+
88+ this . dataStateService . loadData ( result . metadata , result . obo , result . diaf , 'github' ) ;
89+ await this . router . navigate ( [ '/metadata' ] ) ;
90+ } catch ( err ) {
91+ this . githubError . set ( ( err as Error ) . message ) ;
92+ } finally {
93+ this . isGithubLoading . set ( false ) ;
94+ }
95+ }
96+
97+ onGithubRepoInput ( event : Event ) : void {
98+ const target = event . target as HTMLInputElement | null ;
99+ this . githubRepo . set ( target ?. value ?? '' ) ;
100+ }
101+
102+ onGithubBranchInput ( event : Event ) : void {
103+ const target = event . target as HTMLInputElement | null ;
104+ this . githubBranch . set ( target ?. value ?? '' ) ;
105+ }
106+
107+ onGithubTokenInput ( event : Event ) : void {
108+ const target = event . target as HTMLInputElement | null ;
109+ this . githubToken . set ( target ?. value ?? '' ) ;
110+ }
111+
112+ onGithubAuthorNameInput ( event : Event ) : void {
113+ const target = event . target as HTMLInputElement | null ;
114+ this . githubAuthorName . set ( target ?. value ?? '' ) ;
115+ }
116+
117+ onGithubAuthorEmailInput ( event : Event ) : void {
118+ const target = event . target as HTMLInputElement | null ;
119+ this . githubAuthorEmail . set ( target ?. value ?? '' ) ;
120+ }
121+
122+ private restoreGithubPrefs ( ) : void {
123+ if ( ! this . isBrowser ( ) ) return ;
124+
125+ const token = this . readSessionValue ( this . storageKeys . githubToken ) ;
126+ const authorName = this . readLocalValue ( this . storageKeys . githubAuthorName ) ;
127+ const authorEmail = this . readLocalValue ( this . storageKeys . githubAuthorEmail ) ;
128+
129+ if ( token ) this . githubToken . set ( token ) ;
130+ if ( authorName ) this . githubAuthorName . set ( authorName ) ;
131+ if ( authorEmail ) this . githubAuthorEmail . set ( authorEmail ) ;
132+ }
133+
134+ private setupGithubPersistence ( ) : void {
135+ effect ( ( ) => {
136+ this . writeSessionValue ( this . storageKeys . githubToken , this . githubToken ( ) ) ;
137+ } ) ;
138+
139+ effect ( ( ) => {
140+ this . writeLocalValue ( this . storageKeys . githubAuthorName , this . githubAuthorName ( ) ) ;
141+ } ) ;
142+
143+ effect ( ( ) => {
144+ this . writeLocalValue ( this . storageKeys . githubAuthorEmail , this . githubAuthorEmail ( ) ) ;
145+ } ) ;
146+ }
147+
148+ private isBrowser ( ) : boolean {
149+ return typeof window !== 'undefined' ;
150+ }
151+
152+ private readLocalValue ( key : string ) : string {
153+ if ( ! this . isBrowser ( ) ) return '' ;
154+ try {
155+ return window . localStorage . getItem ( key ) ?? '' ;
156+ } catch {
157+ return '' ;
158+ }
159+ }
160+
161+ private writeLocalValue ( key : string , value : string ) : void {
162+ if ( ! this . isBrowser ( ) ) return ;
163+ try {
164+ if ( ! value ) {
165+ window . localStorage . removeItem ( key ) ;
166+ } else {
167+ window . localStorage . setItem ( key , value ) ;
168+ }
169+ } catch {
170+ return ;
171+ }
172+ }
173+
174+ private readSessionValue ( key : string ) : string {
175+ if ( ! this . isBrowser ( ) ) return '' ;
176+ try {
177+ return window . sessionStorage . getItem ( key ) ?? '' ;
178+ } catch {
179+ return '' ;
180+ }
181+ }
182+
183+ private writeSessionValue ( key : string , value : string ) : void {
184+ if ( ! this . isBrowser ( ) ) return ;
185+ try {
186+ if ( ! value ) {
187+ window . sessionStorage . removeItem ( key ) ;
188+ } else {
189+ window . sessionStorage . setItem ( key , value ) ;
190+ }
191+ } catch {
192+ return ;
193+ }
194+ }
195+
51196 async onSelectFolder ( ) : Promise < void > {
52197 // If File System Access API is supported, use it
53198 if ( this . supportsFileSystemAccess ( ) ) {
0 commit comments