Skip to content

Commit

Permalink
initial ephemeral ts (omegaup#7711)
Browse files Browse the repository at this point in the history
# Description
I downloaded the `goldenLayout` package instead of using a script tag
for importing. I imported the newly merged TypeScript components,
everything is working as intended. I modified the components to import
the Vuex `store` variable directly rather than passing it as a prop.
I added a new grader config file to compile the typescript version of
the components.


https://github.com/user-attachments/assets/071c8820-4bcd-420a-9be2-bde5281af145


Fixes: omegaup#7710


# Checklist:

- [x] The code follows the [coding
guidelines](https://github.com/omegaup/omegaup/wiki/Coding-guidelines)
of omegaUp.
- [ ] The tests were executed and all of them passed.
- [ ] If you are creating a feature, the new tests were added.
- [ ] If the change is large (> 200 lines), this PR was split into
various Pull Requests. It's preferred to create one PR for changes in
controllers + unit tests in PHPUnit, and then another Pull Request for
UI + tests in Jest, Cypress or both.
  • Loading branch information
HNOONa-0 authored Aug 1, 2024
1 parent 0316233 commit 30d4dd2
Show file tree
Hide file tree
Showing 13 changed files with 1,142 additions and 76 deletions.
2 changes: 0 additions & 2 deletions frontend/www/grader/ephemeral/templates/index-light.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

<title>omegaUp problemless grader &alpha;</title>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/goldenlayout.min.js"></script>

<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-base.css" />
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-light-theme.css" />
Expand Down
3 changes: 0 additions & 3 deletions frontend/www/grader/ephemeral/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

<title>omegaUp problemless grader &alpha;</title>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/goldenlayout.min.js"></script>

<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-base.css" />
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-dark-theme.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
Expand Down
30 changes: 14 additions & 16 deletions frontend/www/js/omegaup/graderv2/CaseSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@
<script lang="ts">
// TODO: replace all instances of any with correct type
import { Vue, Component, Prop } from 'vue-property-decorator';
import store from './GraderStore';
import * as Util from './util';
import T from '../lang';
@Component
export default class CaseSelector extends Vue {
@Prop({ required: true }) store!: any;
@Prop({ required: true }) storeMapping!: any;
@Prop({ default: 'vs-dark' }) theme!: string;
Expand All @@ -111,19 +111,17 @@ export default class CaseSelector extends Vue {
get summary(): string {
if (
this.store.state.dirty ||
!this.store.state.results ||
!this.store.state.results.verdict
store.state.dirty ||
!store.state.results ||
!store.state.results.verdict
) {
return '';
}
return `${this.store.state.results.verdict} ${this.score(
this.store.state.results,
)}`;
return `${store.state.results.verdict} ${this.score(store.state.results)}`;
}
get groups(): { [key: string]: any }[] {
const flatCases: any = Util.vuexGet(this.store, this.storeMapping.cases);
const flatCases: any = Util.vuexGet(store, this.storeMapping.cases);
const resultMap: { [key: string]: any } = {};
for (const caseName in flatCases) {
Expand Down Expand Up @@ -156,26 +154,26 @@ export default class CaseSelector extends Vue {
}
get currentCase(): string {
return Util.vuexGet(this.store, this.storeMapping.currentCase);
return Util.vuexGet(store, this.storeMapping.currentCase);
}
set currentCase(value) {
Util.vuexSet(this.store, this.storeMapping.currentCase, value);
Util.vuexSet(store, this.storeMapping.currentCase, value);
}
caseResult(caseName: string): null | any {
const flatCaseResults = this.store.getters.flatCaseResults;
const flatCaseResults = store.getters.flatCaseResults;
if (
this.store.state.dirty ||
store.state.dirty ||
!Object.prototype.hasOwnProperty.call(flatCaseResults, caseName)
)
return null;
return flatCaseResults[caseName];
}
groupResult(groupName: string): null | any {
const results = this.store.state.results;
if (this.store.state.dirty || !results || !results.groups) return null;
const results = store.state.results;
if (store.state.dirty || !results || !results.groups) return null;
for (const group of results.groups) {
if (group.group == groupName) return group;
}
Expand Down Expand Up @@ -235,7 +233,7 @@ export default class CaseSelector extends Vue {
createCase(): void {
if (!this.newCaseName) return;
this.store.commit('createCase', {
store.commit('createCase', {
name: this.newCaseName,
weight: parseFloat(this.newCaseWeight.toString()),
});
Expand All @@ -245,7 +243,7 @@ export default class CaseSelector extends Vue {
}
removeCase(name: string): void {
this.store.commit('removeCase', name);
store.commit('removeCase', name);
}
}
</script>
Expand Down
6 changes: 3 additions & 3 deletions frontend/www/js/omegaup/graderv2/DiffEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<script lang="ts">
// TODO: replace all instances of any with correct type
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import store from './GraderStore';
import * as Util from './util';
import * as monaco from 'monaco-editor';
@Component
export default class DiffEditor extends Vue {
@Prop({ required: true }) store!: any;
@Prop({ required: true }) storeMapping!: any;
@Prop({ default: 'vs-dark' }) theme!: string;
@Prop({ default: false }) readOnly!: boolean;
Expand All @@ -20,11 +20,11 @@ export default class DiffEditor extends Vue {
_editor: monaco.editor.IStandaloneDiffEditor | null = null;
get originalContents(): string {
return Util.vuexGet(this.store, this.storeMapping.originalContents);
return Util.vuexGet(store, this.storeMapping.originalContents);
}
get modifiedContents(): string {
return Util.vuexGet(this.store, this.storeMapping.modifiedContents);
return Util.vuexGet(store, this.storeMapping.modifiedContents);
}
@Watch('originalContents')
Expand Down
14 changes: 12 additions & 2 deletions frontend/www/js/omegaup/graderv2/GraderStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ const storeOptions: StoreOptions<GraderStore> = {
'request.input.interactive.main_source'(state: GraderStore) {
return state.request.input.interactive?.main_source || '';
},
'request.input.interactive.language'(state: GraderStore) {
return state.request.input.interactive?.language || '';
},
Tolenrance(state: GraderStore) {
return state.request.input.validator?.tolerance || -1;
},
isCustomValidator(state: GraderStore) {
return !!state.request.input.validator.custom_validator;
},
Expand Down Expand Up @@ -530,7 +536,9 @@ const storeOptions: StoreOptions<GraderStore> = {

// update with interactive problem templates for each language
// dont forget to update all cppxx and pyx templates
for (const extension in templates) {
for (const lang in templates) {
const extension = Util.supportedLanguages[lang].extension;

if (Object.prototype.hasOwnProperty.call(templates, extension)) {
for (const language of Util.extensionToLanguages[extension]) {
interactiveTemplates[language] = templates[extension];
Expand Down Expand Up @@ -574,7 +582,7 @@ const storeOptions: StoreOptions<GraderStore> = {
});
// if we call this function, we must set current case
// or it could cause errors
state.currentCase = caseData.name;
store.commit('currentCase', caseData.name);
state.dirty = true;
},
removeCase(state: GraderStore, name: string) {
Expand Down Expand Up @@ -645,3 +653,5 @@ const storeOptions: StoreOptions<GraderStore> = {
strict: true,
};
const store = new Vuex.Store<GraderStore>(storeOptions);
store.commit('reset');
export default store;
76 changes: 38 additions & 38 deletions frontend/www/js/omegaup/graderv2/IDESettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
import RadioSwitch from '../components/RadioSwitch.vue';
import store from './GraderStore';
import * as Util from './util';
import T from '../lang';
@Component({
Expand All @@ -128,100 +130,98 @@ import T from '../lang';
},
})
export default class IDESettings extends Vue {
@Prop({ required: true }) store!: any;
@Prop({ required: true }) storeMapping!: any;
T = T;
get timeLimit() {
return this.store.state.request.input.limits.TimeLimit;
get timeLimit(): number {
return Util.parseDuration(store.state.request.input.limits.TimeLimit);
}
set timeLimit(value: number) {
this.store.commit('TimeLimit', Number.parseFloat(value.toString()));
store.commit('TimeLimit', value.toString());
}
get overallWallTimeLimit() {
return this.store.state.request.input.limits.OverallWallTimeLimit;
get overallWallTimeLimit(): number {
return Util.parseDuration(
store.state.request.input.limits.OverallWallTimeLimit,
);
}
set overallWallTimeLimit(value: number) {
this.store.commit(
'OverallWallTimeLimit',
Number.parseFloat(value.toString()),
);
store.commit('OverallWallTimeLimit', value.toString());
}
get extraWallTime() {
return this.store.state.request.input.limits.ExtraWallTime;
get extraWallTime(): number {
return Util.parseDuration(store.state.request.input.limits.ExtraWallTime);
}
set extraWallTime(value: number) {
this.store.commit('ExtraWallTime', Number.parseFloat(value.toString()));
store.commit('ExtraWallTime', value.toString());
}
get memoryLimit() {
return this.store.state.request.input.limits.MemoryLimit;
get memoryLimit(): number {
return Util.parseDuration(store.state.request.input.limits.MemoryLimit);
}
set memoryLimit(value: number) {
this.store.commit('MemoryLimit', Number.parseInt(value.toString()));
store.commit('MemoryLimit', Number.parseInt(value.toString()));
}
get outputLimit() {
return this.store.state.request.input.limits.OutputLimit;
get outputLimit(): number {
return Util.parseDuration(store.state.request.input.limits.OutputLimit);
}
set outputLimit(value: number) {
this.store.commit('OutputLimit', Number.parseInt(value.toString()));
store.commit('OutputLimit', Number.parseInt(value.toString()));
}
get validator() {
return this.store.state.request.input.validator.name;
get validator(): string {
return store.state.request.input.validator.name;
}
set validator(value: string) {
this.store.commit('Validator', value);
store.commit('Validator', value);
}
get tolerance() {
return this.store.state.request.input.validator.tolerance;
get tolerance(): number {
return store.getters.Tolerance;
}
set tolerance(value: number) {
this.store.commit('Tolerance', value);
store.commit('Tolerance', value);
}
get validatorLanguage() {
return this.store.state.request.input.validator.custom_validator?.language;
get validatorLanguage(): string {
return store.getters['request.input.validator.custom_validator.language'];
}
set validatorLanguage(value: string) {
this.store.commit('ValidatorLanguage', value);
store.commit('ValidatorLanguage', value);
}
get interactive() {
return this.store.getters.isInteractive;
get interactive(): boolean {
return store.getters.isInteractive;
}
set interactive(value: boolean) {
if (value) this.store.commit('Interactive', {});
else this.store.commit('Interactive', undefined);
if (value) store.commit('Interactive', {});
else store.commit('Interactive', undefined);
}
get interactiveLanguage() {
return this.store.state.request.input.interactive.language;
get interactiveLanguage(): string {
return store.getters['request.input.interactive.language'];
}
set interactiveLanguage(value: string) {
this.store.commit('InteractiveLanguage', value);
store.commit('InteractiveLanguage', value);
}
get interactiveModuleName() {
return this.store.state.request.input.interactive.module_name;
get interactiveModuleName(): string {
return store.getters.moduleName;
}
set interactiveModuleName(value: string) {
this.store.commit('InteractiveModuleName', value);
store.commit('InteractiveModuleName', value);
}
}
</script>
10 changes: 5 additions & 5 deletions frontend/www/js/omegaup/graderv2/MonacoEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<script lang="ts">
// TODO: replace all instances of any with correct type
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import store from './GraderStore';
import * as Util from './util';
import * as monaco from 'monaco-editor';
@Component
export default class MonacoEditor extends Vue {
@Prop({ required: true }) store!: any;
@Prop({ required: true }) storeMapping!: any;
@Prop({ default: 'vs-dark' }) theme!: string;
@Prop({ default: null }) initialModule!: string | null;
Expand All @@ -23,20 +23,20 @@ export default class MonacoEditor extends Vue {
get language(): string {
if (this.initialLanguage) return this.initialLanguage;
return Util.vuexGet(this.store, this.storeMapping.language);
return Util.vuexGet(store, this.storeMapping.language);
}
get module(): string {
if (this.initialModule) return this.initialModule;
return Util.vuexGet(this.store, this.storeMapping.module);
return Util.vuexGet(store, this.storeMapping.module);
}
get contents(): string {
return Util.vuexGet(this.store, this.storeMapping.contents);
return Util.vuexGet(store, this.storeMapping.contents);
}
set contents(value: string) {
Util.vuexSet(this.store, this.storeMapping.contents, value);
Util.vuexSet(store, this.storeMapping.contents, value);
}
get filename(): string {
Expand Down
8 changes: 4 additions & 4 deletions frontend/www/js/omegaup/graderv2/TextEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
<script lang="ts">
// TODO: replace all instances of any with correct type
import { Vue, Prop, Component } from 'vue-property-decorator';
import store from './GraderStore';
import * as Util from './util';
@Component
export default class TextEditor extends Vue {
@Prop({ required: true }) store!: any;
@Prop({ required: true }) storeMapping!: any;
@Prop({ required: true }) extension!: string;
@Prop({ default: null }) module!: string | null;
Expand All @@ -25,20 +25,20 @@ export default class TextEditor extends Vue {
get filename(): string {
if (typeof this.storeMapping.module !== 'undefined') {
return `${Util.vuexGet(this.store, this.storeMapping.module)}.${
return `${Util.vuexGet(store, this.storeMapping.module)}.${
this.extension
}`;
}
return `${this.module}.${this.extension}`;
}
get contents(): string {
return Util.vuexGet(this.store, this.storeMapping.contents);
return Util.vuexGet(store, this.storeMapping.contents);
}
set contents(value: string) {
if (this.readOnly) return;
Util.vuexSet(this.store, this.storeMapping.contents, value);
Util.vuexSet(store, this.storeMapping.contents, value);
}
get title(): string {
Expand Down
Loading

0 comments on commit 30d4dd2

Please sign in to comment.