Skip to content

Commit

Permalink
UI toc generation components, WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
daneryl committed Feb 16, 2021
1 parent bc0d5a4 commit b0616c9
Show file tree
Hide file tree
Showing 21 changed files with 361 additions and 27 deletions.
5 changes: 2 additions & 3 deletions app/api/files/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ export const files = {
return toDeleteFiles;
},

async tocReviewed(_id: string) {
async tocReviewed(_id: string, language) {
const savedFile = await files.save({ _id, generatedToc: false });
const sameEntityFiles = await files.get({ entity: savedFile.entity }, { generatedToc: 1 });
const [entity] = await entities.get({
sharedId: savedFile.entity,
language: savedFile.language,
});

await entities.save(
Expand All @@ -50,7 +49,7 @@ export const files = {
false
),
},
{ user: {}, language: savedFile.language }
{ user: {}, language }
);

return savedFile;
Expand Down
2 changes: 1 addition & 1 deletion app/api/files/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default (app: Application) => {
}),
async (req, res, next) => {
try {
res.json(await files.tocReviewed(req.body.fileId));
res.json(await files.tocReviewed(req.body.fileId, req.language));
} catch (e) {
next(e);
}
Expand Down
2 changes: 0 additions & 2 deletions app/api/files/specs/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const fixtures: DBFixture = {
{
_id: uploadId,
entity: 'sharedId1',
language: 'es',
generatedToc: true,
originalname: 'upload1',
filename: fileName1,
Expand All @@ -22,7 +21,6 @@ const fixtures: DBFixture = {
{
_id: uploadId2,
generatedToc: true,
language: 'es',
entity: 'sharedId1',
filename: 'fileNotInDisk',
},
Expand Down
7 changes: 6 additions & 1 deletion app/react/App/scss/modules/_toc.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
.toc {
padding: 15px;
padding: 0px 15px 15px 15px;
}

div.tocHeader {
padding-left: 15px;
border-bottom: 1px solid #f4f4f4;
}

.toc-view{
Expand Down
11 changes: 9 additions & 2 deletions app/react/Attachments/components/File.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { APIURL } from 'app/config.js';
import { LocalForm, Control } from 'react-redux-form';
import { updateFile, deleteFile } from 'app/Attachments/actions/actions';
import { wrapDispatch } from 'app/Multireducer';
import { TocGeneratedLabel } from 'app/ToggledFeatures/tocGeneration';
import { NeedAuthorization } from 'app/Auth';
import { EntitySchema } from 'shared/types/entityType';
import { ViewDocumentLink } from './ViewDocumentLink';
Expand Down Expand Up @@ -102,7 +103,10 @@ export class File extends Component<FileProps, FileState> {
<div>
<div className="file-language">
<Translate>{language ? transformLanguage(language) || '' : ''}</Translate>
</div>{' '}
</div>
<TocGeneratedLabel file={this.props.file}>
<Translate>ML TOC</Translate>
</TocGeneratedLabel>
<a
href={`${APIURL}files/${filename}`}
target="_blank"
Expand Down Expand Up @@ -206,4 +210,7 @@ export class File extends Component<FileProps, FileState> {
const mapDispatchToProps = (dispatch: Dispatch<{}>, props: FileProps) =>
bindActionCreators({ updateFile, deleteFile }, wrapDispatch(dispatch, props.storeKey));

export const ConnectedFile = connect(null, mapDispatchToProps)(File);
export const ConnectedFile = connect(
null,
mapDispatchToProps
)(File);
3 changes: 2 additions & 1 deletion app/react/Attachments/components/specs/File.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { LocalForm } from 'react-redux-form';
import { FileType } from 'shared/types/fileType';
import { File, FileProps } from '../File';
import { Translate } from 'app/I18N';
import { File, FileProps } from '../File';

describe('file', () => {
let component: ShallowWrapper<File>;
Expand Down Expand Up @@ -32,6 +32,7 @@ describe('file', () => {
});

const render = () => {
//eslint-disable-next-line react/jsx-props-no-spreading
component = shallow(<File {...props} />, { context });
};

Expand Down
15 changes: 14 additions & 1 deletion app/react/Documents/components/DocumentSidePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import ShowIf from 'app/App/ShowIf';
import SidePanel from 'app/Layout/SidePanel';
import DocumentSemanticSearchResults from 'app/SemanticSearch/components/DocumentResults';
import { CopyFromEntity } from 'app/Metadata/components/CopyFromEntity';
import { FeatureToggle } from 'app/components/Elements/FeatureToggle';
import { TocGeneratedLabel, ReviewTocButton } from 'app/ToggledFeatures/tocGeneration';
import { Icon } from 'UI';

import * as viewerModule from 'app/Viewer';
Expand Down Expand Up @@ -321,11 +323,14 @@ export class DocumentSidePanel extends Component {
<div className="sidepanel-footer">
<button
onClick={() => this.props.editToc(this.props.file.toc || [])}
className="edit-toc btn btn-success"
className="edit-toc btn btn-info"
>
<Icon icon="pencil-alt" />
<span className="btn-label">Edit</span>
</button>
<ReviewTocButton file={this.props.file}>
<Translate>Mark as Reviewed</Translate>
</ReviewTocButton>
</div>
</ShowIf>
</NeedAuthorization>
Expand All @@ -340,6 +345,14 @@ export class DocumentSidePanel extends Component {
/>
</TabContent>
<TabContent for="toc">
<div className="tocHeader">
<h1>
<Translate>Table of contents</Translate>
</h1>
<TocGeneratedLabel file={this.props.file}>
<Translate>auto-created ⓘ </Translate>
</TocGeneratedLabel>
</div>
<ShowIf if={!this.props.tocBeingEdited}>
<ShowToc
toc={defaultDocumentToC}
Expand Down
7 changes: 5 additions & 2 deletions app/react/Documents/components/ShowToc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { scrollTo } from 'app/Viewer/actions/uiActions';
import Immutable from 'immutable';
import ShowIf from 'app/App/ShowIf';
import { t } from 'app/I18N';
import { t, Translate} from 'app/I18N';
import { Icon } from 'UI';

export class ShowToc extends Component {
Expand Down Expand Up @@ -66,4 +66,7 @@ function mapDispatchToProps() {
return { scrollTo };
}

export default connect(null, mapDispatchToProps)(ShowToc);
export default connect(
null,
mapDispatchToProps
)(ShowToc);
7 changes: 6 additions & 1 deletion app/react/Library/actions/libraryActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { toUrlParams } from 'shared/JSONRequest';
import { RequestParams } from 'app/utils/RequestParams';
import { store } from 'app/store';
import searchAPI from 'app/Search/SearchAPI';
import { tocGenerationUtils } from 'app/ToggledFeatures/tocGeneration';
import { selectedDocumentsChanged, maybeSaveQuickLabels } from './quickLabelActions';

export function enterLibrary() {
Expand Down Expand Up @@ -245,11 +246,15 @@ export function searchDocuments(
searchParams.sort = '_score';
}

//
// searchParams.aggregateGeneratedToc = true;
//

if (currentSearch.userSelectedSorting) {
dispatch(actions.set(`${storeKey}.selectedSorting`, currentSearch));
}

setSearchInUrl(searchParams);
setSearchInUrl(tocGenerationUtils.aggregations(searchParams, getState().settings.toJS()));
};
}

Expand Down
1 change: 1 addition & 0 deletions app/react/Library/actions/specs/filterActions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ describe('filterActions', () => {
};

store = {
settings: Immutable.fromJS({}),
library: {
filters: Immutable.fromJS(filtersState),
search,
Expand Down
22 changes: 10 additions & 12 deletions app/react/Library/actions/specs/libraryActions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ describe('libraryActions', () => {

beforeEach(() => {
dispatch = jasmine.createSpy('dispatch');
getState = jasmine
.createSpy('getState')
.and.returnValue({ library: { filters: Immutable.fromJS(filters), search: {} } });
getState = jasmine.createSpy('getState').and.returnValue({
settings: Immutable.Map({}),
library: { filters: Immutable.fromJS(filters), search: {} },
});
});

it('should dispatch a SET_LIBRARY_TEMPLATES action ', () => {
Expand Down Expand Up @@ -178,15 +179,15 @@ describe('libraryActions', () => {
{
name: 'relationshipfilter',
type: 'relationshipfilter',
filters: [
{ name: 'status', type: 'select' },
{ name: 'empty', type: 'date' },
],
filters: [{ name: 'status', type: 'select' }, { name: 'empty', type: 'date' }],
},
],
documentTypes: ['decision'],
};
store = { library: { filters: Immutable.fromJS(state), search: { searchTerm: 'batman' } } };
store = {
settings: Immutable.Map({}),
library: { filters: Immutable.fromJS(state), search: { searchTerm: 'batman' } },
};
spyOn(browserHistory, 'getCurrentLocation').and.returnValue({
pathname: '/library',
query: { view: 'chart' },
Expand Down Expand Up @@ -365,10 +366,7 @@ describe('libraryActions', () => {
},
{
type: types.UPDATE_DOCUMENTS,
docs: [
{ sharedId: '1', metadataResponse },
{ sharedId: '2', metadataResponse },
],
docs: [{ sharedId: '1', metadataResponse }, { sharedId: '2', metadataResponse }],
},
];
const store = mockStore({});
Expand Down
34 changes: 34 additions & 0 deletions app/react/ToggledFeatures/tocGeneration/ReviewTocButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { Icon } from 'UI';
import { FeatureToggle } from 'app/components/Elements/FeatureToggle';
import { connect, ConnectedProps } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { ClientFile } from 'app/istore';
import { tocGenerationActions } from './actions';

export interface ReviewTocButtonProps {
file: ClientFile;
children: JSX.Element | string;
}

const mapDispatchToProps = (dispatch: Dispatch<{}>) =>
bindActionCreators({ onClick: tocGenerationActions.reviewToc }, dispatch);

const connector = connect(null, mapDispatchToProps);

type MappedProps = ConnectedProps<typeof connector>;
type ComponentProps = ReviewTocButtonProps & MappedProps;

const ReviewTocButton = ({ file, onClick, children }: ComponentProps) => (
<FeatureToggle feature="tocGeneration">
{file.generatedToc && (
<button type="button" onClick={() => onClick(file._id)} className="edit-toc btn btn-success">
<Icon icon="pencil-alt" />
<span className="btn-label">{children}</span>
</button>
)}
</FeatureToggle>
);

const container = connector(ReviewTocButton);
export { container as ReviewTocButton };
14 changes: 14 additions & 0 deletions app/react/ToggledFeatures/tocGeneration/TocGeneratedLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { FeatureToggle } from 'app/components/Elements/FeatureToggle';
import { FileType } from 'shared/types/fileType';

export interface TocGeneratedLabelProps {
file: FileType;
children: JSX.Element | string;
}

export const TocGeneratedLabel = ({ file, children }: TocGeneratedLabelProps) => (
<FeatureToggle feature="tocGeneration">
{file.generatedToc && <span className="label-generatedToc">{children}</span>}
</FeatureToggle>
);
34 changes: 34 additions & 0 deletions app/react/ToggledFeatures/tocGeneration/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { actions } from 'app/BasicReducer/reducer';
import { actions as formActions } from 'react-redux-form';
import { RequestParams } from 'app/utils/RequestParams';
import api from 'app/utils/api';
import { notificationActions } from 'app/Notifications';

const tocGenerationActions = {
reviewToc(fileId: string) {
return async (dispatch, getState) => {
const currentDoc = getState().documentViewer.doc.toJS();
dispatch(formActions.reset('documentViewer.sidepanel.metadata'));

const updatedFile = (await api.post('files/tocReviewed', new RequestParams({ fileId }))).json;
//WTF
updatedFile.pdfInfo = {}
const doc = {
...currentDoc,
defaultDoc: updatedFile,
documents: currentDoc.documents.map(d => {
if (d._id === updatedFile._id) {
return updatedFile;
}
return d;
}),
};

dispatch(notificationActions.notify('Document updated', 'success'));
dispatch(formActions.reset('documentViewer.sidepanel.metadata'));
dispatch(actions.set('viewer/doc', doc));
};
},
};

export { tocGenerationActions };
3 changes: 3 additions & 0 deletions app/react/ToggledFeatures/tocGeneration/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { TocGeneratedLabel } from './TocGeneratedLabel';
export { ReviewTocButton } from './ReviewTocButton';
export { tocGenerationUtils } from './utils';
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import configureStore, { MockStore, MockStoreCreator } from 'redux-mock-store';
import { Provider } from 'react-redux';
import { FileType } from 'shared/types/fileType';
import { ReviewTocButton } from '../ReviewTocButton';

describe('ReviewTocButton', () => {
let component: ShallowWrapper<typeof ReviewTocButton>;

const mockStoreCreator: MockStoreCreator<object> = configureStore<object>([]);
const render = (file: FileType) => {
const store: MockStore<object> = mockStoreCreator({});
component = shallow(
<Provider store={store}>
<ReviewTocButton file={file}>
<span>test</span>
</ReviewTocButton>
</Provider>
)
.dive()
.dive();
};

it('should render nothing if file generatedToc is false', () => {
render({ generatedToc: false });
expect(component.find('button').length).toEqual(0);

render({});
expect(component.find('button').length).toEqual(0);
});

it('should render when generatedToc is true', () => {
render({ generatedToc: true });
expect(component.find('button').length).toEqual(1);
});
});
Loading

0 comments on commit b0616c9

Please sign in to comment.