Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d53c12e
Organize MC advanced component authoring using tabs
hirokiterashima Mar 31, 2026
b349c0b
Added "Activity" in the dialog title
hirokiterashima Mar 31, 2026
53e42d4
Created shared module.
hirokiterashima Mar 31, 2026
19d54ee
Organize OR advanced component authoring using tabs
hirokiterashima Apr 1, 2026
80d7f01
Organize HTML advanced component authoring using tabs
hirokiterashima Apr 1, 2026
c0a2fd7
Organize Match advanced component authoring using tabs
hirokiterashima Apr 1, 2026
cca2728
Organize Discussion advanced component authoring using tabs
hirokiterashima Apr 1, 2026
f5cb57b
Organize AiChat advanced component authoring using tabs
hirokiterashima Apr 1, 2026
ce6f31d
Organize Animation advanced component authoring using tabs
hirokiterashima Apr 1, 2026
b6dbe43
Organize AudioOscillator advanced component authoring using tabs
hirokiterashima Apr 1, 2026
2a709e2
Update tests
hirokiterashima Apr 1, 2026
52f3b76
Organize ConceptMap advanced component authoring using tabs
hirokiterashima Apr 1, 2026
aa59817
Organize Embedded advanced component authoring using tabs
hirokiterashima Apr 1, 2026
ea8f344
Remove EditCommonAdvanced. No longer used.
hirokiterashima Apr 1, 2026
cbebc62
Organize DialogGuidance advanced component authoring using tabs
hirokiterashima Apr 1, 2026
bde0def
Organize Draw advanced component authoring using tabs
hirokiterashima Apr 2, 2026
2b7e96a
Organize Graph advanced component authoring using tabs
hirokiterashima Apr 2, 2026
5701fdb
Organize Table advanced component authoring using tabs
hirokiterashima Apr 2, 2026
0f0da98
Organize Summary advanced component authoring using tabs
hirokiterashima Apr 2, 2026
bb01855
Organize ShowMyWork advanced component authoring using tabs
hirokiterashima Apr 2, 2026
cec4087
Organize ShowGroupWork advanced component authoring using tabs
hirokiterashima Apr 2, 2026
fc74f5f
Organize OutsideUrl advanced component authoring using tabs
hirokiterashima Apr 2, 2026
f82985c
Organize PeerChat advanced component authoring using tabs
hirokiterashima Apr 2, 2026
5fd5416
Organize Label advanced component authoring using tabs
hirokiterashima Apr 2, 2026
5685dd6
Got summary authoring working again.
hirokiterashima Apr 3, 2026
eacb4c3
Disable mat tab animations
hirokiterashima Apr 3, 2026
6ee2e52
Component rubric authoring: remove button to toggle tinymce, and show…
hirokiterashima Apr 7, 2026
82acda6
Merge branch 'develop' into organize-activity-advanced-authoring-usin…
hirokiterashima Apr 9, 2026
94ec8b3
Show visibility icon if component has constraints. Click on it to ope…
hirokiterashima Apr 9, 2026
1b7770e
Edit component JSON: remove toggle and show textarea when tab is opened.
hirokiterashima Apr 9, 2026
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 @@ -10,8 +10,11 @@ import { moveObjectDown, moveObjectUp } from '../../../assets/wise5/common/array
export abstract class EditAdvancedComponentComponent {
component: Component;
componentContent: ComponentContent;
protected selectedTabIndex: number = 0;

@Input() componentId: string;
@Input() nodeId: string;
@Input() tab: string = 'general';

constructor(
protected nodeService: TeacherNodeService,
Expand All @@ -23,6 +26,15 @@ export abstract class EditAdvancedComponentComponent {
this.componentContent = this.teacherProjectService.getComponent(this.nodeId, this.componentId);
this.component = new Component(this.componentContent, this.nodeId);
this.teacherProjectService.uiChanged();

switch (this.tab) {
case 'visibility':
this.selectedTabIndex = 1;
break;
default:
this.selectedTabIndex = 0;
break;
}
}

setShowSubmitButtonValue(show: boolean = false): void {
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,45 +1,60 @@
import { Component, Input } from '@angular/core';
import { Component as WISEComponent } from '../../../assets/wise5/common/Component';
import { TeacherProjectService } from '../../../assets/wise5/services/teacherProjectService';
import { EditConnectedComponentsComponent } from '../edit-connected-components/edit-connected-components.component';
import { EditComponentWidthComponent } from '../edit-component-width/edit-component-width.component';
import { EditComponentTagsComponent } from '../edit-component-tags/edit-component-tags.component';
import { NgModule } from '@angular/core';
import { EditComponentDefaultFeedback } from '../edit-advanced-component/edit-component-default-feedback/edit-component-default-feedback.component';
import { EditComponentExcludeFromTotalScoreComponent } from '../edit-component-exclude-from-total-score/edit-component-exclude-from-total-score.component';
import { EditComponentMaxScoreComponent } from '../edit-component-max-score/edit-component-max-score.component';
import { EditComponentMaxSubmitComponent } from '../edit-component-max-submit/edit-component-max-submit.component';
import { EditComponentRubricComponent } from '../edit-component-rubric/edit-component-rubric.component';
import { EditComponentSaveButtonComponent } from '../edit-component-save-button/edit-component-save-button.component';
import { EditComponentSubmitButtonComponent } from '../edit-component-submit-button/edit-component-submit-button.component';
import { EditComponentRubricComponent } from '../edit-component-rubric/edit-component-rubric.component';
import { EditComponentJsonComponent } from '../edit-component-json/edit-component-json.component';
import { EditComponentMaxSubmitComponent } from '../edit-component-max-submit/edit-component-max-submit.component';
import { EditComponentMaxScoreComponent } from '../edit-component-max-score/edit-component-max-score.component';
import { EditComponentExcludeFromTotalScoreComponent } from '../edit-component-exclude-from-total-score/edit-component-exclude-from-total-score.component';
import { EditComponentDefaultFeedback } from '../edit-advanced-component/edit-component-default-feedback/edit-component-default-feedback.component';
import { EditComponentTagsComponent } from '../edit-component-tags/edit-component-tags.component';
import { EditComponentWidthComponent } from '../edit-component-width/edit-component-width.component';
import { EditComponentConstraintsComponent } from '../edit-component-constraints/edit-component-constraints.component';
import { EditComponentJsonComponent } from '../edit-component-json/edit-component-json.component';
import { MatTabsModule } from '@angular/material/tabs';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { FormsModule } from '@angular/forms';
import { EditComponentAddToNotebookButtonComponent } from '../edit-component-add-to-notebook-button/edit-component-add-to-notebook-button.component';
import { EditConnectedComponentsComponent } from '../edit-connected-components/edit-connected-components.component';

@Component({
@NgModule({
imports: [
EditComponentConstraintsComponent,
EditComponentAddToNotebookButtonComponent,
EditComponentSaveButtonComponent,
EditComponentSubmitButtonComponent,
EditComponentMaxSubmitComponent,
EditConnectedComponentsComponent,
EditComponentDefaultFeedback,
EditComponentExcludeFromTotalScoreComponent,
EditComponentMaxScoreComponent,
EditComponentMaxSubmitComponent,
EditComponentJsonComponent,
EditComponentExcludeFromTotalScoreComponent,
EditComponentWidthComponent,
EditComponentRubricComponent,
EditComponentTagsComponent,
EditComponentConstraintsComponent,
EditComponentJsonComponent,
FormsModule,
MatCheckboxModule,
MatIconModule,
MatTabsModule
],
exports: [
EditComponentAddToNotebookButtonComponent,
EditComponentSaveButtonComponent,
EditComponentSubmitButtonComponent,
EditComponentTagsComponent,
EditComponentMaxSubmitComponent,
EditConnectedComponentsComponent,
EditComponentDefaultFeedback,
EditComponentMaxScoreComponent,
EditComponentExcludeFromTotalScoreComponent,
EditComponentWidthComponent,
EditConnectedComponentsComponent
],
selector: 'edit-common-advanced',
templateUrl: './edit-common-advanced.component.html'
EditComponentRubricComponent,
EditComponentTagsComponent,
EditComponentConstraintsComponent,
EditComponentJsonComponent,
FormsModule,
MatCheckboxModule,
MatIconModule,
MatTabsModule
]
})
export class EditCommonAdvancedComponent {
@Input() allowedConnectedComponentTypes: string[] = [];
@Input() component: WISEComponent;

constructor(protected projectService: TeacherProjectService) {}

protected connectedComponentsChanged(connectedComponents: any[]): void {
this.component.content.connectedComponents = connectedComponents;
this.projectService.nodeChanged();
}
}
export class EditComponentAdvancedSharedModule {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h2 mat-dialog-title i18n>Advanced Settings</h2>
<h2 mat-dialog-title i18n>Advanced Activity Settings</h2>
<mat-divider />
<div mat-dialog-content>
<div #component></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ describe('EditComponentAdvancedComponent', () => {
{
provide: MAT_DIALOG_DATA,
useValue: {
content: { type: 'ShowMyWork' },
id: 'component1',
nodeId: 'node1'
component: {
content: { type: 'ShowMyWork' },
id: 'component1',
nodeId: 'node1'
},
tab: 'general'
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,22 @@ export class EditComponentAdvancedComponent {
private componentRef: ComponentRef<WISEComponent>;
constructor(
private applicationRef: ApplicationRef,
@Inject(MAT_DIALOG_DATA) protected component: WISEComponent,
@Inject(MAT_DIALOG_DATA) protected data: { component: WISEComponent; tab?: string },
private injector: EnvironmentInjector
) {}

ngAfterViewInit(): void {
this.componentRef = createComponent(components[this.component.content.type].authoringAdvanced, {
hostElement: this.componentElementRef.nativeElement,
environmentInjector: this.injector
});
this.componentRef = createComponent(
components[this.data.component.content.type].authoringAdvanced,
{
hostElement: this.componentElementRef.nativeElement,
environmentInjector: this.injector
}
);
Object.assign(this.componentRef.instance, {
nodeId: this.component.nodeId,
componentId: this.component.id
nodeId: this.data.component.nodeId,
componentId: this.data.component.id,
tab: this.data.tab
});
this.applicationRef.attachView(this.componentRef.hostView);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
<div class="flex flex-row justify-start items-center gap-2">
<mat-label class="node__label--vertical-alignment" i18n>JSON</mat-label>
<button
mat-raised-button
color="primary"
class="topButton"
(click)="toggleJSONView()"
matTooltip="Show JSON"
i18n-matTooltip
matTooltipPosition="above"
>
<mat-icon>code</mat-icon>
</button>
</div>
@if (showJSONAuthoring) {
<div class="flex flex-col gap-2">
<span i18n style="color: red">Close the JSON view to save the changes</span>
<mat-form-field class="w-full">
<mat-label i18n>Edit Activity JSON</mat-label>
<textarea
matInput
cdkTextareaAutosize
[(ngModel)]="componentContentJSONString"
(ngModelChange)="jsonChanged.next($event)"
></textarea>
</mat-form-field>
<div class="pt-4">
<div class="mb-2">
<mat-icon color="warn" class="align-bottom">warning</mat-icon>
<span i18n class="warn">
Editing the JSON directly is generally not recommended, as errors can break the unit. If you
need assistance, please contact WISE staff.
</span>
</div>
}
<mat-form-field class="w-full" appearance="outline" style="margin-top: 10px">
<mat-label i18n>Edit Activity JSON</mat-label>
<textarea
class="mat-body-2"
matInput
cdkTextareaAutosize
[(ngModel)]="componentContentJSONString"
(ngModelChange)="jsonChanged.next($event)"
></textarea>
</mat-form-field>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,26 @@ import { MatButtonModule } from '@angular/material/button';
MatTooltipModule
],
selector: 'edit-component-json',
styles: ['div { margin-top: 10px; margin-bottom: 10px; } .mat-icon { margin: 0px; }'],
styles: ['.mat-icon { margin: 0px; }'],
templateUrl: 'edit-component-json.component.html'
})
export class EditComponentJsonComponent {
@Input() component: WISEComponent;
protected componentContentJSONString: string;
protected jsonChanged: Subject<string> = new Subject<string>();
protected showJSONAuthoring: boolean = false;
private subscriptions: Subscription = new Subscription();
private validComponentContentJSONString: string;

constructor(
private notificationService: NotificationService,
private projectService: TeacherProjectService
) {}

ngOnInit(): void {
this.setComponentContentJsonString();
this.subscriptions.add(
this.jsonChanged.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(() => {
if (this.isJSONValid()) {
this.rememberRecentValidJSON();
this.notificationService.showJSONValidMessage();
} else {
this.notificationService.showJSONInvalidMessage();
}
})
);
this.componentContentJSONString = JSON.stringify(this.component.content, null, 4);
this.subscriptions.add(
this.projectService.nodeChanged$.subscribe(() => {
this.setComponentContentJsonString();
this.jsonChanged.pipe(debounceTime(1000), distinctUntilChanged()).subscribe((newText) => {
this.componentContentJSONString = newText;
this.saveChanges();
})
);
}
Expand All @@ -62,55 +51,15 @@ export class EditComponentJsonComponent {
this.subscriptions.unsubscribe();
}

private setComponentContentJsonString(): void {
this.componentContentJSONString = JSON.stringify(this.component.content, null, 4);
}

protected toggleJSONView(): void {
if (this.showJSONAuthoring) {
if (this.isJSONValid()) {
this.saveChanges();
this.showJSONAuthoring = false;
} else {
const doRollback = confirm(
$localize`The JSON is invalid. Invalid JSON will not be saved.\nClick "OK" to revert back to the last valid JSON.\nClick "Cancel" to keep the invalid JSON open so you can fix it.`
);
if (doRollback) {
this.rollbackToRecentValidJSON();
this.saveChanges();
}
}
} else {
this.showJSONAuthoring = true;
this.rememberRecentValidJSON();
}
}

private isJSONValid(): boolean {
try {
JSON.parse(this.componentContentJSONString);
return true;
} catch (e) {
return false;
}
}

private saveChanges(): void {
try {
this.projectService
.getNode(this.component.nodeId)
.replaceComponent(this.component.id, JSON.parse(this.componentContentJSONString));
this.projectService.componentChanged();
this.notificationService.showJSONValidMessage();
} catch (e) {
this.notificationService.showJSONInvalidMessage();
}
}

private rememberRecentValidJSON(): void {
this.validComponentContentJSONString = this.componentContentJSONString;
}

private rollbackToRecentValidJSON(): void {
this.componentContentJSONString = this.validComponentContentJSONString;
}
}

This file was deleted.

Loading
Loading