Skip to content
This repository was archived by the owner on Jul 17, 2025. It is now read-only.

Commit a8cc634

Browse files
authored
update QA (#364)
* combine setdata step 2/3 together * combine QA setdata step 2/3 together * hot fix delete project error (#361) * hot fix project dataset map issue (#362) * update QA setdata export and annotation auto select words
1 parent 5084b9f commit a8cc634

File tree

6 files changed

+78
-47
lines changed

6 files changed

+78
-47
lines changed

annotation-app/src/app/components/projects/annotate/annotate.component.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,6 +2818,7 @@ export class AnnotateComponent implements OnInit, AfterViewInit, OnDestroy {
28182818
selection = window.getSelection();
28192819

28202820
if (selection.isCollapsed) return [];
2821+
selection = this.extendWordSelection(selection);
28212822
const mySelf = document.getElementsByClassName('nerPassage')[0];
28222823

28232824
for (i = 0; i < selection.rangeCount; i++) {
@@ -2870,6 +2871,38 @@ export class AnnotateComponent implements OnInit, AfterViewInit, OnDestroy {
28702871
return ranges;
28712872
}
28722873

2874+
extendWordSelection(selection){
2875+
if (this.projectType != 'qa') {
2876+
return selection;
2877+
}
2878+
2879+
let range = document.createRange();
2880+
range.setStart(selection.anchorNode, selection.anchorOffset);
2881+
range.setEnd(selection.focusNode, selection.focusOffset);
2882+
let backwards = range.collapsed;
2883+
range.detach();
2884+
2885+
// modify() works on the focus of the selection
2886+
let endNode = selection.focusNode;
2887+
let endOffset = selection.focusOffset;
2888+
selection.collapse(selection.anchorNode, selection.anchorOffset);
2889+
2890+
let direction = [];
2891+
if (backwards) {
2892+
direction = ['backward', 'forward'];
2893+
} else {
2894+
direction = ['forward', 'backward'];
2895+
}
2896+
2897+
selection.modify("move", direction[0], "character");
2898+
selection.modify("move", direction[1], "word");
2899+
selection.extend(endNode, endOffset);
2900+
selection.modify("extend", direction[1], "character");
2901+
selection.modify("extend", direction[0], "word");
2902+
2903+
return selection;
2904+
}
2905+
28732906
initNerPassage(element, selectedEntityID0) {
28742907
if (element.start === element.end) return;
28752908
this.createNewRange(element, selectedEntityID0);

annotation-app/src/app/components/projects/create-project.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,11 @@ export class CreateNewComponent implements OnInit {
393393
);
394394
formData.append(
395395
'selectLabels',
396-
this.msg.type === 'ner' ? JSON.stringify(this.checkboxChecked) : this.dropdownSelected,
396+
this.msg.type === 'ner'
397+
? JSON.stringify(this.checkboxChecked)
398+
: this.msg.type === 'qa'
399+
? JSON.stringify([])
400+
: this.dropdownSelected,
397401
);
398402

399403
formData.append('ticketQuestions', JSON.stringify(this.helpfulText));

annotation-app/src/app/components/projects/set-data/set-data.component.html

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,18 @@
4242
</clr-wizard-page>
4343
<!-- select label -->
4444
<clr-wizard-page
45-
[clrWizardPageNextDisabled]="(wizardData.projectType !== 'qa' && !selectedDropDownItem) || !formPageOne.valid"
45+
*ngIf="wizardData.projectType != 'qa'"
46+
[clrWizardPageNextDisabled]="!selectedDropDownItem || !formPageOne.valid"
4647
(clrWizardPageOnLoad)="clrWizardPageOnLoad('page2')"
4748
>
4849
<ng-template clrPageTitle>{{
4950
wizardData.projectType === 'ner'
5051
? 'Please select a single text column which you intend to present to annotators to annotate'
51-
: wizardData.projectType === 'qa'
52-
? 'Please select the question column which you intend to labels from'
5352
: 'Please select the column which you intend to calculate labels from'
5453
}}</ng-template>
5554
<ng-template clrPageNavTitle>{{
5655
wizardData.projectType === 'ner'
5756
? 'Select Text Column'
58-
: wizardData.projectType === 'qa'
59-
? 'Select Question Column'
6057
: 'Select Label Column'
6158
}}</ng-template>
6259
<form clrForm #formPageOne="ngForm">
@@ -72,13 +69,15 @@
7269
[clrWizardPageNextDisabled]="wizardData.projectType === 'ner' ? false : selectDescription.length == 0"
7370
>
7471
<ng-template clrPageNavTitle>
75-
{{ wizardData.projectType === 'ner' ? 'Select Helpful Column' : 'Select Text Column' }}
72+
{{ wizardData.projectType === 'ner' ? 'Select Helpful Column' : wizardData.projectType === 'qa'? 'Select Column':'Select Text Column' }}
7673
</ng-template>
7774

7875
<ng-template clrPageTitle>
7976
{{
8077
wizardData.projectType === 'ner'
8178
? 'Select the columns to present to annotators about the existing labels (optional) or helpful text (optional)'
79+
: wizardData.projectType === 'qa'
80+
? 'Select the question column and text column to present to annotators'
8281
: 'Select the columns to present to annotators'
8382
}}
8483
</ng-template>
@@ -88,6 +87,10 @@
8887
<div *ngIf="wizardData.projectType === 'qa'">
8988
<app-clr-select
9089
[data]="clrSelectData"
90+
(valueChange)="onReceiveSelectedItem($event)">
91+
</app-clr-select>
92+
<app-clr-select
93+
[data]="clrSelectData2"
9194
(valueChange)="onReciveSelectedText($event)">
9295
</app-clr-select>
9396
</div>

annotation-app/src/app/components/projects/set-data/set-data.component.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class SetDataComponent implements OnInit, OnChanges {
3434
selectDescription = [];
3535
checkboxColumns = [];
3636
clrSelectData = {};
37+
clrSelectData2 = {};
3738
isLoading: boolean;
3839
formDatagrid: any;
3940

@@ -68,7 +69,12 @@ export class SetDataComponent implements OnInit, OnChanges {
6869
this.clrSelectData = {
6970
required: false,
7071
options: [...this.wizardData.csvHeaders],
71-
labelText: 'Select The Column',
72+
labelText: 'Select Question Column',
73+
};
74+
this.clrSelectData2 = {
75+
required: true,
76+
options: [...this.wizardData.csvHeaders],
77+
labelText: 'Select Text Column',
7278
};
7379
}else{
7480
this.clrSelectData = {

annotation-service/services/file-service.js

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,11 @@ async function prepareHeaders(project, format) {
181181
} else if (project.projectType == PROJECTTYPE.LOG) {
182182
headerArray.push({ id: "fileName", title: "fileName" });
183183
headerArray.push({ id: "freeText", title: "freeText" });
184-
} else {
184+
} else if(project.projectType == PROJECTTYPE.QA){
185+
headerArray.push({ id: 'context', title: 'context' });
186+
headerArray.push({ id: 'question', title: 'question' });
187+
headerArray.push({ id: 'answers', title: 'answers' });
188+
}else {
185189
await project.selectedColumn.forEach(item => {
186190
headerArray.push({ id: item, title: item });
187191
});
@@ -196,10 +200,7 @@ async function prepareHeaders(project, format) {
196200
await labelsArray.forEach(item => {
197201
headerArray.push({ id: item, title: item });
198202
});
199-
} else if(project.projectType == PROJECTTYPE.QA){
200-
headerArray.push({ id: 'Questions', title: 'Questions' });
201-
headerArray.push({ id: 'Answers', title: 'Answers' });
202-
}else {
203+
} else if(project.projectType != PROJECTTYPE.QA){
203204
await project.categoryList.split(",").forEach(item => {
204205
headerArray.push({ id: item, title: item });
205206
});
@@ -314,52 +315,34 @@ async function prepareContents(srData, project, format) {
314315
newCase[item] = newCase[item][0] ? JSON.stringify(newCase[item]) : [];
315316
});
316317
} else if(project.projectType == PROJECTTYPE.QA){
317-
// init selected data
318-
await project.selectedColumn.forEach(item => {
319-
newCase[item] = (srs.originalData)[item];
320-
});
318+
// take user input or reviewed info
319+
const userInputDatas = await prepareUserInputs(srs);
321320
// init questions cloumn
322321
let questionForText = srs.questionForText;
323-
// init pop-up lables
324-
await project.popUpLabels.forEach(item => {
325-
newCase[item] = [];
326-
});
327-
328-
const userInputDatas = await prepareUserInputs(srs);
329322
if (srs.reviewInfo.modified) {
330323
questionForText = userInputDatas[0].questionForText;
331324
}
332325
// init answer cloumn
333-
let answersList = [];
334326
for await(const item of userInputDatas) {
335-
//answers cloumn data
336327
for await(const question of questionForText) {
337-
let answer = {question: question, answers: []};
328+
let answers = {text: [], answer_start: []};
338329
for await(const lb of item.problemCategory) {
339330
if (lb.label === question) {
340-
answer['answers'].push([lb.text, lb.start, lb.end]);
341-
}
342-
}
343-
await answersList.push(answer);
344-
}
345-
346-
//popup lablels
347-
for await(const label of project.popUpLabels) {
348-
for await(const lb of item.problemCategory) {
349-
if (lb.popUpLabel === label) {
350-
newCase[label].push([lb.text, lb.start, lb.end])
331+
answers['text'].push(lb.text);
332+
answers['answer_start'].push(lb.start);
351333
}
352334
}
335+
// current question has answer
336+
if (answers.text.length) {
337+
cvsData.push({
338+
context: Object.values(srs.originalData)[0],
339+
question: question,
340+
answers: JSON.stringify(answers)
341+
});
342+
}
353343
}
354344
}
355-
//add questions column
356-
newCase['Questions'] = await JSON.stringify(questionForText);
357-
//add answers cloumn
358-
newCase['Answers'] = await JSON.stringify(answersList);
359-
//change annotations pop-up labels to a string array
360-
await project.popUpLabels.forEach(item => {
361-
newCase[item] = newCase[item][0] ? JSON.stringify(newCase[item]) : [];
362-
});
345+
363346
}else if (project.projectType == PROJECTTYPE.LOG) {
364347
// init log classification fileName
365348
newCase.fileName = srs.fileInfo.fileName;
@@ -492,7 +475,9 @@ async function prepareContents(srData, project, format) {
492475
}
493476
}
494477
}
495-
cvsData.push(newCase);
478+
if (project.projectType != PROJECTTYPE.QA) {
479+
cvsData.push(newCase);
480+
}
496481
}
497482
return cvsData;
498483
}

annotation-service/utils/imgImporter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async function execute(req, sendEmail, annotators) {
5858
}
5959
emailService.sendEmailToAnnotator(param).catch(err => console.error(`[ IMAGE ][ ERROR ] send email:`, err));
6060
}
61-
await updateDatasetProjectInfo(selectedDataset, req.body.pname, OPERATION.ADD)
61+
await updateDatasetProjectInfo(req.body.selectedDataset, req.body.pname, OPERATION.ADD)
6262
console.log(`[ IMAGE ] Utils imgImporter.execute end: `, Date.now());
6363

6464
}

0 commit comments

Comments
 (0)