Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,39 @@ <h5 class="modal-title">Add Notebook</h5>
<label>Do you want to add a new notebook or create one from an existing URL?</label>
<select #types class="form-control" aria-label="Default select example"
(change)="onChange(types.value)">
<option selected value="true">Create a new one</option>
<option value="false">Add an existing one</option>
<option selected value="file">Create a new one from a file</option>
<option value="url">Add an existing one from URL</option>
<option value="blank">Create a blank notebook</option>
</select>
</div>

<div class="form-group" *ngIf="showCreateNotebook">
<label>Create Notebook</label>
<input type="file" class="form-control p-1" placeholder="" (change)="fileEvent($event)" />
<input type="file" class="form-control p-1" placeholder="" (change)="fileEvent($event)" formControlName="notebookFile" required/>
<div *ngIf="uploadNotebookForm.get('notebookFile')?.touched && uploadNotebookForm.get('notebookFile')?.errors"
class="text-danger">
<span *ngIf="uploadNotebookForm.get('notebookFile')?.errors?.['required']">File is required</span>
</div>
</div>

<div class="form-group" *ngIf="showAddExistingNotebook">
<label for="notebookURL">Notebook Type</label>
<select #notebookTypes class="form-control" aria-label="Default select example"
(change)="onChangeNotebookType(notebookTypes.value)">
<option selected value="jupyter">Jupyter</option>
<option selected value="colab">Google Colab</option>
<option value="observablehq">ObservableHQ</option>
<option value="colab">Google Colab</option>
</select>
</div>

<div class="form-group" *ngIf="showAddExistingNotebook">
<label for="notebookURL">Add Existing Notebook (URL)</label>
<input formControlName="notebookURL" type="text" class="form-control" placeholder=""
(change)="urlEvent($event)" [readOnly]="isLoading" />
<div *ngIf="uploadNotebookForm.get('notebookURL')?.touched && uploadNotebookForm.get('notebookURL')?.errors"
class="text-danger">
<span *ngIf="uploadNotebookForm.get('notebookURL')?.errors?.['required']">URL is required</span>
<span *ngIf="uploadNotebookForm.get('notebookURL')?.errors?.['pattern']">Enter a valid URL</span>
</div>
</div>

<div class="form-group" *ngIf="showAddExistingNotebook && notebookType==='observablehq'">
Expand All @@ -65,11 +74,18 @@ <h5 class="modal-title">Add Notebook</h5>
</button>
</div>
</div>

<div class="form-group" *ngIf="showBlankNotebook">
<label>Create Blank Notebook</label>
<p class="text-muted mb-0">
A minimal Jupyter notebook (<code>.ipynb</code>) will be generated.
</p>
</div>
</div>
<div class="modal-footer justify-content-center">
<!-- Form Group Register -->
<div class="form-group">
<button type="submit" class="btn" [disabled]="notebookName.invalid" (click)="addNotebook()">
<button type="submit" class="btn" [disabled]="uploadNotebookForm.invalid" (click)="addNotebook()">
<div>
<span>Add Notebook</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ export class ModalUploadNotebookComponent implements OnInit {
uploadNotebookForm: FormGroup;
notebookName: FormControl;
notebookURL: FormControl;
notebookFile: FormControl;
isLoading: Boolean;
notebook: NotebookFile;
existingNotebookURL: NotebookURL;
showCreateNotebook: Boolean;
showAddExistingNotebook: Boolean;
showBlankNotebook: boolean;
file: File;
url: string;
notebookType: "jupyter" | "observablehq" | "colab" = "jupyter";
notebookType: "observablehq" | "colab" = "colab";

datasets: ObservableHQDataset[] = [];

Expand All @@ -37,37 +39,82 @@ export class ModalUploadNotebookComponent implements OnInit {
ngOnInit(): void {
// console.log(this.project);
this.showCreateNotebook = true;
this.showAddExistingNotebook = false;
this.showBlankNotebook = false;

this.notebookName = new FormControl('', [Validators.required, Validators.minLength(1), Validators.maxLength(20)]);
this.notebookURL = new FormControl('');
this.notebookFile = new FormControl(null);

this.uploadNotebookForm = this.formBuilder.group({
'notebookName': this.notebookName,
'notebookURL': this.notebookURL
'notebookURL': this.notebookURL,
'notebookFile': this.notebookFile
});

this.applyModeValidators('file');
}

onChange(selectedType) {
if (selectedType === "true") {
this.showCreateNotebook = true;
this.showAddExistingNotebook = false;
}
else {
this.showCreateNotebook = false;
this.showAddExistingNotebook = true;
private applyModeValidators(mode: string) {
if (mode === 'file') {
this.notebookFile.setValidators([Validators.required]);
this.notebookURL.clearValidators();
} else if (mode === 'url'){
this.notebookURL.setValidators([
Validators.required,
Validators.pattern(/^(https?:\/\/)[^\s]+$/i)
]);
this.notebookFile.clearValidators();
} else {
this.notebookFile.clearValidators();
this.notebookURL.clearValidators();
}
this.notebookFile.updateValueAndValidity();
this.notebookURL.updateValueAndValidity();
}

onChange(selected: string) {
this.showCreateNotebook = selected === 'file';
this.showAddExistingNotebook = selected === 'url';
this.showBlankNotebook = selected === 'blank';

this.applyModeValidators(selected as 'file' | 'url' | 'blank');
}

onChangeNotebookType(selectedType) {
this.notebookType = selectedType;
}

fileEvent($event) {
this.file = $event.target.files[0];
const input = $event.target as HTMLInputElement;
this.file = (input.files && input.files[0]) || null;
this.uploadNotebookForm.patchValue({ notebookFile: this.file });
this.notebookFile.updateValueAndValidity();
}

urlEvent($event) {
this.url = $event.target.value;
const input = $event.target as HTMLInputElement;
this.url = input.value;
this.uploadNotebookForm.patchValue({ notebookURL: this.url });
this.notebookURL.updateValueAndValidity();
}

private buildBlankNotebookFile(): File {
const title = this.notebookName.value?.trim() || 'Untitled';
const content = {
cells: [
{
cell_type: 'code',
metadata: {},
source: [``]
}
],
metadata: {},
nbformat: 4,
nbformat_minor: 2
};
const blob = new Blob([JSON.stringify(content, null, 2)], { type: 'application/json' });
return new File([blob], `${title}.ipynb`, { type: 'application/json' });
}

addNotebook() {
Expand All @@ -89,7 +136,9 @@ export class ModalUploadNotebookComponent implements OnInit {
this.closeModal.emit();
this.getNotebooks.emit(this.currentDirectory);
});
return;
}

if (this.showAddExistingNotebook) {
if (this.notebookType === "observablehq") {
let datasetMap = {
Expand Down Expand Up @@ -122,6 +171,21 @@ export class ModalUploadNotebookComponent implements OnInit {
this.closeModal.emit();
this.getNotebooks.emit(this.currentDirectory);
});
return;
}

if (this.showBlankNotebook) {
const blankFile = this.buildBlankNotebookFile();
const payload: NotebookFile = {
file: blankFile,
name: this.notebookName.value,
projectID: this.project.projectID
};
this.projectService.uploadNotebook(payload, this.currentDirectory).subscribe(result => {
this.closeModal.emit();
this.getNotebooks.emit(this.currentDirectory);
});
return;
}
}

Expand Down
22 changes: 0 additions & 22 deletions src/Analysim.Web/Controllers/ProjectController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,28 +1223,6 @@ public async Task<IActionResult> UploadExistingNotebook([FromForm] ExistingProje
await _dbContext.SaveChangesAsync();


}
else if (noteBookData.Type == "jupyter")
{
string fileName = noteBookData.Directory + $"{noteBookData.NotebookName}.ipynb";
newNotebook = new Notebook
{
Container = "notebook-" + project.Name.ToLower(),
Directory = noteBookData.Directory,
Name = Path.GetFileNameWithoutExtension(noteBookData.NotebookName),
Extension = Path.GetExtension(fileName),
Size = 0,
Uri = notebookUrl,
DateCreated = DateTimeOffset.Now.UtcDateTime,
LastModified = DateTimeOffset.Now.UtcDateTime,
ProjectID = noteBookData.ProjectID,
type = "jupyter",
Route = user.UserName + "/" + project.Name
};

await _dbContext.Notebook.AddAsync(newNotebook);
await _dbContext.SaveChangesAsync();

}
else
{
Expand Down