Skip to content

Commit

Permalink
Merge pull request #129 from kbss-cvut/1545-analyze-select-vocabulary
Browse files Browse the repository at this point in the history
1545 analyze select vocabulary
  • Loading branch information
ledsoft authored Apr 1, 2021
2 parents c27a2ef + f703bb0 commit 7d7effc
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 203 deletions.
6 changes: 3 additions & 3 deletions src/component/annotator/Annotator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import TermOccurrence, {TextQuoteSelector} from "../../model/TermOccurrence";
import {setTermDefinitionSource} from "../../action/AsyncTermActions";
import JsonLdUtils from "../../util/JsonLdUtils";
import Utils from "../../util/Utils";
import TextAnalysisButtonAnnotatorWrapper from "./TextAnalysisButtonAnnotatorWrapper";
import AnnotatorContent from "./AnnotatorContent";
import withI18n, {HasI18n} from "../hoc/withI18n";
import {injectIntl} from "react-intl";
Expand All @@ -33,6 +32,7 @@ import HeaderWithActions from "../misc/HeaderWithActions";
import {Card, CardBody, CardHeader} from "reactstrap";
import VocabularyIriLink from "../vocabulary/VocabularyIriLink";
import File from "../../model/File";
import TextAnalysisInvocationButton from "./TextAnalysisInvocationButton";

interface AnnotatorProps extends HasI18n {
fileIri: IRI;
Expand Down Expand Up @@ -402,8 +402,8 @@ export class Annotator extends React.Component<AnnotatorProps, AnnotatorState> {
<CardBody>
<LegendToggle key="legend-toggle"/>
<IfUserAuthorized key="text-analysis-button" renderUnauthorizedAlert={false}>
<TextAnalysisButtonAnnotatorWrapper fileIri={this.props.fileIri}
vocabularyIri={this.props.vocabularyIri}/>
<TextAnalysisInvocationButton className="analyze-button" fileIri={this.props.fileIri}
defaultVocabularyIri={IRIImpl.toString(this.props.vocabularyIri)}/>
</IfUserAuthorized>
<CreateTermFromAnnotation ref={this.createNewTermDialog}
show={this.state.showNewTermDialog} onClose={this.onCloseCreate}
Expand Down
16 changes: 0 additions & 16 deletions src/component/annotator/TextAnalysisButtonAnnotatorWrapper.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import * as React from "react";
import {injectIntl} from "react-intl";
import withI18n, {HasI18n} from "../../hoc/withI18n";
import withInjectableLoading, {InjectsLoading} from "../../hoc/withInjectableLoading";
import withI18n, {HasI18n} from "../hoc/withI18n";
import withInjectableLoading, {InjectsLoading} from "../hoc/withInjectableLoading";
import {GoClippy} from "react-icons/go";
import {Button} from "reactstrap";
import {connect} from "react-redux";
import {ThunkDispatch} from "../../../util/Types";
import {executeFileTextAnalysis} from "../../../action/AsyncActions";
import {publishNotification} from "../../../action/SyncActions";
import NotificationType from "../../../model/NotificationType";
import ResourceSelectVocabulary from "../ResourceSelectVocabulary";
import Vocabulary from "../../../model/Vocabulary";
import {IRI} from "../../../util/VocabularyUtils";
import {ThunkDispatch} from "../../util/Types";
import {executeFileTextAnalysis} from "../../action/AsyncActions";
import {publishNotification} from "../../action/SyncActions";
import NotificationType from "../../model/NotificationType";
import ResourceSelectVocabulary from "../resource/ResourceSelectVocabulary";
import Vocabulary from "../../model/Vocabulary";
import {IRI} from "../../util/VocabularyUtils";

interface TextAnalysisInvocationButtonProps extends HasI18n, InjectsLoading {
id?: string;
Expand All @@ -35,11 +35,7 @@ export class TextAnalysisInvocationButton extends React.Component<TextAnalysisIn
}

public onClick = () => {
if (this.props.defaultVocabularyIri) {
this.invokeTextAnalysis(this.props.fileIri,this.props.defaultVocabularyIri);
} else {
this.setState({showVocabularySelector: true});
}
this.setState({showVocabularySelector: true});
};

private invokeTextAnalysis(fileIri: IRI, vocabularyIri: string) {
Expand Down Expand Up @@ -67,13 +63,14 @@ export class TextAnalysisInvocationButton extends React.Component<TextAnalysisIn
return <>
<ResourceSelectVocabulary show={this.state.showVocabularySelector}
defaultVocabularyIri={this.props.defaultVocabularyIri}
onCancel={this.closeVocabularySelect} onSubmit={this.onVocabularySelect}/>
onCancel={this.closeVocabularySelect} onSubmit={this.onVocabularySelect}
title={i18n("file.metadata.startTextAnalysis.vocabularySelect.title")}/>
<Button id={this.props.id}
size="sm"
color="primary"
className={this.props.className}
title={i18n("file.metadata.startTextAnalysis")}
onClick={this.onClick}><GoClippy/>&nbsp;{i18n("file.metadata.startTextAnalysis.text")}
onClick={this.onClick}><GoClippy className="mr-1"/>{i18n("file.metadata.startTextAnalysis.text")}
</Button>
</>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as React from "react";
import File from "../../../../model/File";
import VocabularyUtils, {IRI} from "../../../../util/VocabularyUtils";
import Generator from "../../../../__tests__/environment/Generator";
import File from "../../../model/File";
import VocabularyUtils, {IRI} from "../../../util/VocabularyUtils";
import Generator from "../../../__tests__/environment/Generator";
import {shallow} from "enzyme";
import {TextAnalysisInvocationButton} from "../TextAnalysisInvocationButton";
import {intlFunctions} from "../../../../__tests__/environment/IntlUtil";
import {InjectsLoading} from "../../../hoc/withInjectableLoading";
import ResourceSelectVocabulary from "../../ResourceSelectVocabulary";
import Vocabulary from "../../../../model/Vocabulary";
import {intlFunctions} from "../../../__tests__/environment/IntlUtil";
import {InjectsLoading} from "../../hoc/withInjectableLoading";
import ResourceSelectVocabulary from "../../resource/ResourceSelectVocabulary";
import Vocabulary from "../../../model/Vocabulary";

describe("TextAnalysisInvocationButton", () => {

Expand All @@ -23,6 +23,7 @@ describe("TextAnalysisInvocationButton", () => {
let renderMask: () => JSX.Element | null;

let loadingProps: InjectsLoading;
let vocabulary: Vocabulary;

beforeEach(() => {
file = new File({
Expand All @@ -36,41 +37,45 @@ describe("TextAnalysisInvocationButton", () => {
loadingOff = jest.fn();
renderMask = jest.fn();
loadingProps = {loadingOff, loadingOn, renderMask, loading: false};
vocabulary = Generator.generateVocabulary();
});

it("runs text analysis immediately when defaultVocabulary was specified.", () => {
const vocabularyIri = Generator.generateUri();
vocabulary.iri = vocabularyIri;
const fileIri = VocabularyUtils.create(file.iri);
const wrapper = shallow<TextAnalysisInvocationButton>(<TextAnalysisInvocationButton fileIri={fileIri}
executeTextAnalysis={executeTextAnalysis}
notifyAnalysisFinish={notifyAnalysisFinish}
defaultVocabularyIri={vocabularyIri}
{...loadingProps} {...intlFunctions()}/>);
wrapper.instance().onClick();
wrapper.instance().onVocabularySelect(vocabulary);
expect(executeTextAnalysis).toHaveBeenCalledWith(fileIri, vocabularyIri);
});

it("starts loading when text analysis is invoked", () => {
const fileIri = VocabularyUtils.create(Generator.generateUri());
const vocabularyIri = Generator.generateUri();
vocabulary.iri = vocabularyIri;
const wrapper = shallow<TextAnalysisInvocationButton>(<TextAnalysisInvocationButton fileIri={fileIri}
executeTextAnalysis={executeTextAnalysis}
notifyAnalysisFinish={notifyAnalysisFinish}
defaultVocabularyIri={vocabularyIri}
{...loadingProps} {...intlFunctions()}/>);
wrapper.instance().onClick();
wrapper.instance().onVocabularySelect(vocabulary);
expect(loadingOn).toHaveBeenCalled();
});

it("stops loading after text analysis invocation finishes", () => {
const fileIri = VocabularyUtils.create(Generator.generateUri());
const vocabularyIri = Generator.generateUri();
vocabulary.iri = vocabularyIri;
const wrapper = shallow<TextAnalysisInvocationButton>(<TextAnalysisInvocationButton fileIri={fileIri}
executeTextAnalysis={executeTextAnalysis}
notifyAnalysisFinish={notifyAnalysisFinish}
defaultVocabularyIri={vocabularyIri}
{...loadingProps} {...intlFunctions()}/>);
wrapper.instance().onClick();
wrapper.instance().onVocabularySelect(vocabulary);
return Promise.resolve().then(() => {
expect(loadingOff).toHaveBeenCalled();
});
Expand All @@ -79,12 +84,13 @@ describe("TextAnalysisInvocationButton", () => {
it("publishes notification after text analysis invocation finishes", () => {
const fileIri = VocabularyUtils.create(Generator.generateUri());
const vocabularyIri = Generator.generateUri();
vocabulary.iri = vocabularyIri;
const wrapper = shallow<TextAnalysisInvocationButton>(<TextAnalysisInvocationButton fileIri={fileIri}
executeTextAnalysis={executeTextAnalysis}
notifyAnalysisFinish={notifyAnalysisFinish}
defaultVocabularyIri={vocabularyIri}
{...loadingProps} {...intlFunctions()}/>);
wrapper.instance().onClick();
wrapper.instance().onVocabularySelect(vocabulary);
return Promise.resolve().then(() => {
expect(notifyAnalysisFinish).toHaveBeenCalled();
});
Expand All @@ -104,10 +110,6 @@ describe("TextAnalysisInvocationButton", () => {
});

it("invokes text analysis with selected Vocabulary when Vocabulary selector is submitted", () => {
const vocabulary = new Vocabulary({
iri: Generator.generateUri(),
label: "Test vocabulary"
});
const wrapper = shallow<TextAnalysisInvocationButton>(<TextAnalysisInvocationButton fileIri={VocabularyUtils.create(file.iri)}
executeTextAnalysis={executeTextAnalysis}
notifyAnalysisFinish={notifyAnalysisFinish}
Expand Down
2 changes: 1 addition & 1 deletion src/component/misc/Mask.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "../../styles/custom/colors";

.mask {
position: fixed;
position: fixed !important;
padding: 0;
margin: 0;
top: 0;
Expand Down
25 changes: 18 additions & 7 deletions src/component/resource/ResourceFileDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import Resource, {EMPTY_RESOURCE} from "../../model/Resource";
import File from "../../model/File";
import TermItState from "../../model/TermItState";
import {TextAnalysisRecord} from "../../model/TextAnalysisRecord";
import {Label} from "reactstrap";
import withI18n, {HasI18n} from "../hoc/withI18n";
import {popRoutingPayload} from "../../action/SyncActions";
import Routes from "../../util/Routes";
import {TextQuoteSelector} from "../../model/TermOccurrence";
import VocabularySelect from "../vocabulary/VocabularySelect";
import Vocabulary from "../../model/Vocabulary";
import {Card, CardBody, CardHeader} from "reactstrap";

interface StoreStateProps {
resource: Resource;
Expand Down Expand Up @@ -85,12 +87,12 @@ export class ResourceFileDetail extends React.Component<ResourceFileDetailProps,
return VocabularyUtils.create(fileNamespace + normalizedFileName);
};

private getVocabularyIri(): IRI | null {
private getVocabularyIri(): IRI | undefined {
if (Utils.getPrimaryAssetType(this.props.resource) !== VocabularyUtils.FILE) {
return null;
return undefined;
}
const file = this.props.resource as File;
return file.owner && file.owner.vocabulary ? VocabularyUtils.create(file.owner.vocabulary.iri!) : null;
return file.owner && file.owner.vocabulary ? VocabularyUtils.create(file.owner.vocabulary.iri!) : undefined;
}

private loadLatestTextAnalysisRecord() {
Expand All @@ -103,6 +105,12 @@ export class ResourceFileDetail extends React.Component<ResourceFileDetailProps,
});
}

public onSelectVocabulary = (voc: Vocabulary | null) => {
if (voc) {
this.setState({vocabularyIri: VocabularyUtils.create(voc.iri)});
}
};

public render() {
const resource = this.props.resource;
const vocabularyIri = this.state.vocabularyIri;
Expand All @@ -111,9 +119,12 @@ export class ResourceFileDetail extends React.Component<ResourceFileDetailProps,
return null;
}
if (vocabularyIri === null) {
// This is temporary, annotator should support vocabulary selection
return <Label id="file-detail-no-vocabulary"
className="italics">{this.props.i18n("file.annotate.unknown-vocabulary")}</Label>
return <Card id="file-detail-no-vocabulary" className="w-50 mx-auto">
<CardHeader>{this.props.i18n("file.annotate.selectVocabulary")}</CardHeader>
<CardBody>
<VocabularySelect onVocabularySet={this.onSelectVocabulary} vocabulary={null}/>
</CardBody>
</Card>;
}
return <ContentDetail iri={this.getFileIri()}
scrollTo={this.state.scrollToSelector} vocabularyIri={vocabularyIri}/>
Expand Down
4 changes: 4 additions & 0 deletions src/component/resource/ResourceSelectVocabulary.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.resource-select-vocabulary-modal {
width: fit-content !important;
min-width: 300px;
}
Loading

0 comments on commit 7d7effc

Please sign in to comment.