@@ -13,6 +13,7 @@ import {
1313 type ConnectionsData ,
1414 clone ,
1515 resolveConnectionsReferences ,
16+ type UploadFile ,
1617} from '@microsoft/logic-apps-shared' ;
1718import { useKnowledgeStyles } from './styles' ;
1819import { HttpClient } from '../../designer/app/AzureLogicAppsDesigner/Services/HttpClient' ;
@@ -25,6 +26,7 @@ import {
2526import { addConnectionInJson , addOrUpdateAppSettings } from '../../designer/app/AzureLogicAppsDesigner/Utilities/Workflow' ;
2627import { Spinner } from '@fluentui/react-components' ;
2728import { CustomConnectionParameterEditorService } from '../Services/connectionParameterEditor' ;
29+ import { environment } from '../../environments/environment' ;
2830
2931const apiVersion = '2020-06-01' ;
3032const httpClient = new HttpClient ( ) ;
@@ -86,7 +88,7 @@ export const KnowledgeHub = () => {
8688 < div className = { styles . wizardContent } >
8789 < div className = { styles . wizardWrapper } >
8890 < KnowledgeDataProvider resourceDetails = { resourceDetails } services = { services } isDarkMode = { theme === 'dark' } >
89- < KnowledgeHubWizard />
91+ < KnowledgeHubWizard onUploadArtifact = { uploadFileToKnowledgeHub } />
9092 </ KnowledgeDataProvider >
9193 </ div >
9294 </ div >
@@ -152,3 +154,73 @@ const getServices = (
152154 hostService : { } as any , // Placeholder for IHostService, not used in this context
153155 } ;
154156} ;
157+
158+ const uploadFileToKnowledgeHub = async (
159+ siteResourceId : string ,
160+ hubName : string ,
161+ content : { file : UploadFile ; name : string ; description ?: string } ,
162+ setIsLoading : ( isLoading : boolean ) => void
163+ ) : Promise < void > => {
164+ const { file, name, description } = content ;
165+ const contentType = file . file . type || 'application/octet-stream' ;
166+
167+ const uri = `https://management.azure.com${ siteResourceId } /hostruntime/runtime/webhooks/workflow/api/management/knowledgehubs/${ hubName } /knowledgeArtifacts/${ name } ?api-version=2018-11-01` ;
168+
169+ return new Promise ( ( resolve , reject ) => {
170+ const reader = new FileReader ( ) ;
171+
172+ reader . onload = ( ) => {
173+ const base64Content = ( reader . result as string ) . split ( ',' ) [ 1 ] ; // Remove data URL prefix
174+
175+ const payload = {
176+ description : description ,
177+ payload : {
178+ '$content-type' : contentType ,
179+ $content : base64Content ,
180+ } ,
181+ } ;
182+
183+ const xhr = new XMLHttpRequest ( ) ;
184+
185+ xhr . onloadstart = ( ) => {
186+ setIsLoading ( true ) ;
187+ } ;
188+
189+ xhr . onloadend = ( ) => {
190+ setIsLoading ( false ) ;
191+ file . setProgress ?.( 1 ) ;
192+
193+ if ( xhr . status >= 200 && xhr . status < 300 ) {
194+ resolve ( ) ;
195+ } else {
196+ reject ( new Error ( `Upload failed with status ${ xhr . status } : ${ xhr . statusText } ` ) ) ;
197+ }
198+ } ;
199+
200+ xhr . onerror = ( ) => {
201+ setIsLoading ( false ) ;
202+ reject ( new Error ( 'Upload failed due to network error' ) ) ;
203+ } ;
204+
205+ xhr . upload . onprogress = ( e ) => {
206+ if ( e . lengthComputable ) {
207+ file . setProgress ?.( e . loaded / e . total ) ;
208+ }
209+ } ;
210+
211+ xhr . open ( 'PUT' , uri , true ) ;
212+ xhr . setRequestHeader ( 'Content-Type' , 'application/json' ) ;
213+ xhr . setRequestHeader ( 'Authorization' , `Bearer ${ environment . armToken } ` ) ;
214+ xhr . setRequestHeader ( 'Cache-Control' , 'no-cache' ) ;
215+
216+ xhr . send ( JSON . stringify ( payload ) ) ;
217+ } ;
218+
219+ reader . onerror = ( ) => {
220+ setIsLoading ( false ) ;
221+ reject ( new Error ( 'Failed to read file' ) ) ;
222+ } ;
223+
224+ reader . readAsDataURL ( file . file ) ;
225+ } ) ;
226+ } ;
0 commit comments