Skip to content

Commit

Permalink
Merge pull request #367 from fujaba/refactor/config
Browse files Browse the repository at this point in the history
Refactor Assignments Config
  • Loading branch information
Clashsoft authored Oct 24, 2023
2 parents fad127b + cd0477c commit 6782b76
Show file tree
Hide file tree
Showing 17 changed files with 173 additions and 203 deletions.
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@angular/router": "^16.2.9",
"@angular/service-worker": "^16.2.9",
"@ctrl/ngx-codemirror": "^7.0.0",
"@mean-stream/ngbx": "^0.11.0",
"@mean-stream/ngbx": "^0.12.0",
"@ng-bootstrap/ng-bootstrap": "^15.1.1",
"@popperjs/core": "^2.11.8",
"@sentry/angular-ivy": "^7.74.0",
Expand All @@ -32,6 +32,7 @@
"bootstrap": "~5.2.3",
"bootstrap-darkmode": "^5.0.1",
"bootstrap-icons": "^1.11.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"codemirror": "^5.65.15",
"file-saver": "^2.0.5",
Expand Down
31 changes: 18 additions & 13 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions frontend/src/app/assignment/assignment.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';

import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import {ModalModule} from '@mean-stream/ngbx';
import {FormsModule as NgbxFormsModule, ModalModule} from '@mean-stream/ngbx';
import {ClipboardModule} from 'ngx-clipboard';
import {DndModule} from 'ngx-drag-drop';

import {SharedModule} from '../shared/shared.module';
import {AssignmentRoutingModule} from './assignment-routing.module';
import {AssignmentSharedModule} from './modules/shared/shared.module';
import {ConfigFormComponent} from './pages/config-form/config-form.component';
import {CreateSolutionComponent} from './pages/create-solution/create-solution.component';
import {MyAssignmentsComponent} from './pages/my-assignments/my-assignments.component';
import {MySolutionsComponent} from './pages/my-solutions/my-solutions.component';
Expand Down Expand Up @@ -42,7 +41,6 @@ import {KeycloakBearerInterceptor} from "keycloak-angular";
TokenModalComponent,
OverviewComponent,
SettingsComponent,
ConfigFormComponent,
],
imports: [
CommonModule,
Expand All @@ -55,6 +53,7 @@ import {KeycloakBearerInterceptor} from "keycloak-angular";
AssignmentRoutingModule,
DndModule,
ModalModule,
NgbxFormsModule,
],
providers: [
{
Expand Down
75 changes: 75 additions & 0 deletions frontend/src/app/assignment/model/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {IsBoolean, IsEmail, IsIn, IsNotEmpty, IsString} from "class-validator";
import {Presentation} from "@mean-stream/ngbx";
import {Transform} from "class-transformer";

export class Config {
@Presentation({
description: 'Your full name for use in assignments, solutions, comments and evaluations.',
})
@IsString()
@IsNotEmpty()
name: string = '';

@Presentation({
label: 'E-Mail Address',
description: 'Your email address for use in assignments, solutions, comments and evaluations.',
})
@IsEmail()
email: string = '';

@Presentation({
label: 'IDE',
description: 'Your preferred IDE for cloning repositories.',
optionLabels: {
vscode: 'VSCode',
'code-oss': 'Code - OSS',
vscodium: 'VSCodium',
},
})
@IsIn(['vscode', 'code-oss', 'vscodium'])
ide: 'vscode' | 'code-oss' | 'vscodium' = 'vscode';

@Presentation({
label: 'Git Clone Protocol',
description: 'The protocol to use when cloning a repository.',
optionLabels: {
https: 'HTTPS',
ssh: 'SSH',
},
})
@IsIn(['https', 'ssh'])
cloneProtocol: 'https' | 'ssh' = 'https';

@Presentation({
label: 'Git Clone Ref',
description: 'The ref to use when cloning a repository. ' +
'Tags are only supported in VSCode v1.74+ and Assignments imported after 2022-12-21.',
optionLabels: {
none: 'None',
tag: 'Tag',
},
})
@IsIn(['none', 'tag'])
cloneRef: 'none' | 'tag' = 'tag';

@Presentation({
description: 'Enable Code Search globally.',
})
@IsBoolean()
@Transform(({value}) => value === 'true')
codeSearch = true;

@Presentation({
description: 'Enable Similar Solutions globally.',
})
@IsBoolean()
@Transform(({value}) => value === 'true')
similarSolutions = true;

@Presentation({
description: 'Enable Snippet Suggestions globally.',
})
@IsBoolean()
@Transform(({value}) => value === 'true')
snippetSuggestions = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,6 @@
</ng-template>
</div>
</div>
<div ngbDropdown class="d-inline-block">
<button class="btn btn-outline-secondary" id="optionsDropdown" ngbDropdownToggle ngbTooltip="Options">
<i class="bi-gear"></i>
<span class="visually-hidden">Options</span>
</button>
<div ngbDropdownMenu aria-labelledby="optionsDropdown">
<ng-container *ngFor="let option of optionItems!">
<h6 class="dropdown-header">
{{ option.title }}
<i class="bi-info-circle" [ngbTooltip]="option.description"></i>
</h6>
<button
*ngFor="let item of option.options"
ngbDropdownItem
role="checkbox"
(click)="setOption(option.key, item[0])"
class="dropdown-item-check"
[class.checked]="options[option.key] === item[0]"
>
{{ item[1] }}
</button>
<div class="dropdown-divider"></div>
</ng-container>
<a ngbDropdownItem routerLink="/assignments/settings">
All Settings...
</a>
</div>
</div>
<ng-template #searchHelp>
<ul>
<li>Search terms are separated by spaces and case sensitive</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {Assignee} from '../../../model/assignee';
import Assignment, {ReadAssignmentDto} from '../../../model/assignment';
import Solution, {AuthorInfo, authorInfoProperties} from '../../../model/solution';
import {AssignmentService} from '../../../services/assignment.service';
import {CONFIG_OPTIONS, ConfigKey, ConfigService} from '../../../services/config.service';
import {ConfigService} from '../../../services/config.service';
import {SolutionContainerService} from '../../../services/solution-container.service';
import {SolutionService} from '../../../services/solution.service';
import {TaskService} from '../../../services/task.service';
Expand Down Expand Up @@ -48,7 +48,6 @@ export class SolutionTableComponent implements OnInit {

loading = false;

optionItems = CONFIG_OPTIONS.filter(o => o.options);
options = this.configService.getAll();

search$ = new BehaviorSubject<string>('');
Expand Down Expand Up @@ -132,12 +131,6 @@ export class SolutionTableComponent implements OnInit {
this.userService.getGitHubToken().subscribe(token => this.userToken = token);
}

setOption(key: ConfigKey, value: string) {
// copy is necessary to re-evaluate link pipes
this.options = {...this.options, [key]: value};
this.configService.set(key, value);
}

select(id: string, selected: boolean) {
if (selected) {
this.selected[id] = selected;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Pipe, PipeTransform} from '@angular/core';
import {ReadAssignmentDto} from '../../../model/assignment';
import Solution from '../../../model/solution';
import {ConfigKey} from '../../../services/config.service';
import {Config} from "../../../model/config";


const clonePrefix = {https: 'https://github.com/', ssh: '[email protected]:'};
Expand All @@ -11,16 +11,13 @@ const cloneSuffix = {https: '', ssh: '.git'};
name: 'cloneLink',
})
export class CloneLinkPipe implements PipeTransform {
transform(assignment: ReadAssignmentDto, solution: Solution, options: Record<ConfigKey, string>): string {
transform(assignment: ReadAssignmentDto, solution: Solution, options: Config): string {
const {ide, cloneProtocol, cloneRef} = options;
const user = solution.author.github;
const org = assignment.classroom?.org;
const prefix = assignment.classroom?.prefix;
let ref = '';
switch (cloneRef) {
case 'commit':
ref = `&ref=${solution.commit}`;
break;
case 'tag':
ref = `&ref=assignments/${assignment._id}`;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,8 @@ <h5>
fulibFeedback Settings
</h5>
<p>
Use the button below to configure fulibFeedback and view evaluations for this submission in
<select class="form-control form-control-sm d-inline-block w-auto" [(ngModel)]="ide"
(ngModelChange)="saveIde($event)">
<option *ngFor="let option of ideOption.options" [value]="option[0]">{{ option[1] }}</option>
</select>
.
Use the button below to configure fulibFeedback and view evaluations for this submission in your IDE
<a class="bi-gear" routerLink="/assignments/settings" ngbTooltip="Configure"></a>.
</p>
<a class="btn btn-primary bi-magic"
[href]="ide + '://fulib.fulibfeedback/configure?api_server=' + encodedApiServer + '&assignment=' + assignmentId + '&solution=' + solutionId + '&token=' + token | safeUrl">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {of} from 'rxjs';
import {map, switchMap, tap} from 'rxjs/operators';
import {SolutionService} from 'src/app/assignment/services/solution.service';
import {environment} from '../../../../../environments/environment';
import {CONFIG_OPTIONS, ConfigService} from '../../../services/config.service';
import {ConfigService} from '../../../services/config.service';

@Component({
selector: 'app-solution-share',
Expand All @@ -20,7 +20,6 @@ export class SolutionShareComponent implements OnInit {

readonly origin: string;
readonly encodedApiServer = encodeURIComponent(new URL(environment.assignmentsApiUrl, location.origin).origin);
readonly ideOption = CONFIG_OPTIONS.find(o => o.key === 'ide')!;

constructor(
private solutionService: SolutionService,
Expand Down

This file was deleted.

Empty file.

This file was deleted.

Loading

0 comments on commit 6782b76

Please sign in to comment.