Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds conditional display on pages #4404

Merged
merged 31 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
edab6cb
Added a simple Section component
grafitto Mar 15, 2022
155a890
Renamed Section to EntitySection
grafitto Mar 15, 2022
60071aa
Refactored functions to utils
grafitto Mar 15, 2022
fac7285
Unwrapped metadata and also added docs
grafitto Mar 15, 2022
516e9d0
Fixed linting errors
grafitto Mar 15, 2022
ca2d6ad
Removed doc comment
grafitto Mar 15, 2022
14bf2d7
Reverted utils and only extracted required function
grafitto Mar 15, 2022
b43f46f
Added EntitySection component test
grafitto Mar 15, 2022
230946e
Handled inherited values
grafitto Mar 15, 2022
11cec18
Fixed test
grafitto Mar 16, 2022
164243b
Reverted changes in actions
grafitto Mar 16, 2022
137d797
Extracted a simple component to display on condition
grafitto Mar 16, 2022
63e5601
Renamed props
grafitto Mar 16, 2022
f3b6dfa
Updated tests
grafitto Mar 16, 2022
e20309b
Added a simple Section component
grafitto Mar 15, 2022
05c31c3
Renamed Section to EntitySection
grafitto Mar 15, 2022
92fd49a
Refactored functions to utils
grafitto Mar 15, 2022
5d66234
Unwrapped metadata and also added docs
grafitto Mar 15, 2022
abd5f7c
Fixed linting errors
grafitto Mar 15, 2022
4da4eab
Removed doc comment
grafitto Mar 15, 2022
3578c11
Reverted utils and only extracted required function
grafitto Mar 15, 2022
5a09882
Added EntitySection component test
grafitto Mar 15, 2022
f96d9e4
Handled inherited values
grafitto Mar 15, 2022
151679d
Fixed test
grafitto Mar 16, 2022
0c03997
Reverted changes in actions
grafitto Mar 16, 2022
e9e21ac
Extracted a simple component to display on condition
grafitto Mar 16, 2022
d659062
Renamed props
grafitto Mar 16, 2022
0cc6d3f
Updated tests
grafitto Mar 16, 2022
3eda330
Exported functions when defining instead of below the file
grafitto Mar 21, 2022
3c8a2fb
Merge branch '4231-conditional-display-on-pages' of github.com:hurido…
grafitto Mar 21, 2022
763cb2e
Merge branch 'development' into 4231-conditional-display-on-pages
konzz Mar 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions app/react/Markdown/components/EntityData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { showByType } from 'app/Metadata/components/Metadata';
import { Translate } from 'app/I18N';
import { IImmutable } from 'shared/types/Immutable';
import { ensure } from 'shared/tsUtils';

import { logError } from '../utils';
export interface EntityDataProps {
'value-of'?: string;
'label-of'?: string;
Expand Down Expand Up @@ -66,14 +66,6 @@ const extractMetadataLabel = ({ formattedEntity, propertyName, newNameGeneration
return <Translate context={propertyData.translateContext}>{propertyData.label}</Translate>;
};

const logError = (err: any, propValueOf?: string, propLabelOf?: string) => {
/* eslint-disable no-console */
console.error('Error on EntityData: ');
console.error('value-of: ', propValueOf, '; label-of: ', propLabelOf);
console.error(err);
/* eslint-enable no-console */
};

const getProperty = (
propValueOf?: EntityDataProps['value-of'],
propLabelOf?: EntityDataProps['label-of']
Expand Down
81 changes: 81 additions & 0 deletions app/react/Markdown/components/EntitySection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* eslint-disable react/no-multi-comp */
import { connect, ConnectedProps } from 'react-redux';
import React from 'react';
import { IStore } from 'app/istore';
import { logError } from '../utils';
import { Section } from './Section';

interface EntitySectionProps {
'show-if'?: string;
children: JSX.Element;
}

const mapStateToProps = ({ templates, entityView }: IStore) => ({
entity: entityView.entity,
templates,
});

const connector = connect(mapStateToProps);

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

const getPropertyValue = (property: any, metadataProperty: any) => {
switch (property.type) {
case 'multiselect':
case 'multidaterange':
case 'nested':
case 'multidate':
case 'geolocation':
return metadataProperty.map((v: any) => v.label || v.value);
case 'relationship': {
let value: any[] = [];
metadataProperty.forEach((v: any) => {
if (v.inheritedType && v.inheritedValue) {
const properties = getPropertyValue({ type: v.inheritedType }, v.inheritedValue);
value = Array.isArray(properties) ? [...value, ...properties] : [...value, properties];
} else {
value.push(v.label || v.value);
}
});
return Array.from(new Set(value));
}
case 'generatedid':
return typeof metadataProperty === 'string' ? metadataProperty : metadataProperty[0].value;
default:
return metadataProperty[0].label || metadataProperty[0].value;
}
};

// eslint-disable-next-line import/exports-last
export const UnwrapMetadataObject = (MetadataObject: any, Template: any) =>
Object.keys(MetadataObject).reduce((UnwrapedMO, key) => {
if (!MetadataObject[key].length) {
return UnwrapedMO;
}
const property = Template.properties.find((p: any) => p.name === key);
const propertyValue = getPropertyValue(property, MetadataObject[key]);
return { ...UnwrapedMO, [key]: propertyValue };
}, {});

// eslint-disable-next-line max-statements
const EntitySection = ({ entity, templates, children, 'show-if': showIf }: ComponentProps) => {
const jsEntity = entity.toJS();
const template = templates.find(t => t?.get('_id') === jsEntity.template);
const unwrappedMetadata = UnwrapMetadataObject(jsEntity.metadata, template.toJS());
jsEntity.metadata = unwrappedMetadata;
try {
const condition = JSON.parse(showIf as string);
return (
<Section data={[jsEntity]} showIf={condition}>
{children}
</Section>
);
} catch (e) {
logError(e, showIf);
return null;
}
};

const container = connector(EntitySection);
export { container as EntitySection };
16 changes: 16 additions & 0 deletions app/react/Markdown/components/Section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable react/no-multi-comp */
import sift from 'sift';

interface EntitySectionProps {
showIf: any;
children: JSX.Element;
data: any[];
}

// eslint-disable-next-line max-statements
const Section = ({ data, children, showIf: condition }: EntitySectionProps) => {
const filtered = data.filter(sift(condition));
return filtered.length > 0 ? children : null;
};

export { Section };
2 changes: 2 additions & 0 deletions app/react/Markdown/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Icon } from 'UI';
import Counter from './Counter';
import ContactForm from './ContactForm';
import { EntityData } from './EntityData';
import { EntitySection } from './EntitySection';
import EntityLink from './EntityLink';
import ItemList from './ItemList';
import Repeat from './Repeat';
Expand Down Expand Up @@ -66,4 +67,5 @@ export {
Map,
Link,
EntityInfo,
EntitySection,
};
44 changes: 1 addition & 43 deletions app/react/Markdown/components/specs/EntityData.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
*/
import React from 'react';
import { ReactWrapper } from 'enzyme';
import Immutable from 'immutable';
import { renderConnectedMount } from 'app/utils/test/renderConnected';

import { state } from './fixture/state';
import { EntityData } from '../EntityData';

describe('EntityData Markdown', () => {
Expand All @@ -22,47 +21,6 @@ describe('EntityData Markdown', () => {
});

const render = (innerComponent: any) => {
const state = {
entityView: {
entity: Immutable.fromJS({
template: 't1',
title: 'Entity 1',
creationDate: 1234,
metadata: {
description: [{ value: 'A long description' }],
date: [{ value: 237600000 }],
main_image: [{ value: 'https://www.google.com' }],
},
}),
},
templates: Immutable.fromJS([
{
_id: 't1',
commonProperties: [{ name: 'title', label: 'Title' }],
properties: [
{ name: 'description', type: 'text' },
{ name: 'date', type: 'date' },
{ name: 'main_image', label: 'Main Image', type: 'image' },
],
},
]),
thesauris: Immutable.fromJS([{}]),
translations: Immutable.fromJS([
{
locale: 'en',
contexts: [
{
id: 't1',
values: { Title: 'Title translated', 'Main Image': 'Main Image translated' },
},
],
},
]),
settings: { collection: Immutable.fromJS({ newNameGeneration: true }) },
inlineEdit: Immutable.fromJS({ inlineEdit: false }),
locale: 'en',
};

component = renderConnectedMount(() => innerComponent, state);
};

Expand Down
73 changes: 73 additions & 0 deletions app/react/Markdown/components/specs/EntitySection.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* @jest-environment jsdom
*/
import React from 'react';
import { ReactWrapper } from 'enzyme';
import { renderConnectedMount } from 'app/utils/test/renderConnected';
import { state } from './fixture/state';
import { EntitySection } from '../EntitySection';

describe('EntitySection Markdown', () => {
let component: ReactWrapper<
Readonly<{}> & Readonly<{ children?: React.ReactNode }>,
Readonly<{}>,
React.Component<{}, {}, any>
>;
let consoleErrorSpy: jasmine.Spy;

beforeEach(() => {
consoleErrorSpy = jasmine.createSpy('consoleErrorSpy');
spyOn(console, 'error').and.callFake(consoleErrorSpy);
});

const render = (innerComponent: any) => {
component = renderConnectedMount(() => innerComponent, state);
};

const testShowIf = (showIf: string, expected: string) => {
render(
<EntitySection show-if={showIf}>
<div>test</div>
</EntitySection>
);
expect(component.html()).toBe(expected);
};

describe('root properties Values', () => {
it('should show if title and root dates of entity exists', () => {
testShowIf('{ "title": { "$exists": true }}', '<div>test</div>');
testShowIf('{ "creationDate": { "$exists": true }}', '<div>test</div>');
});
it('should not show if a root property does not exist', () => {
testShowIf('{ "titledoesntexist": { "$exists": true }}', '');
});
});

describe('metadata property Values', () => {
it('should show if unwrapped metadata properties exist', () => {
testShowIf('{ "metadata.description": { "$exists": true }}', '<div>test</div>');
testShowIf('{ "metadata.date": { "$exists": true }}', '<div>test</div>');
testShowIf('{ "metadata.main_image": { "$exists": true }}', '<div>test</div>');
});
it('should show if a metadata property matches a value', () => {
testShowIf('{ "metadata.description": { "$eq": "A long description" }}', '<div>test</div>');
testShowIf('{ "metadata.description": "A long description" }', '<div>test</div>');
});
it('should not show if a metadata property does not exist', () => {
testShowIf('{ "metadata.nonexistent": { "$exists": true }}', '');
});
});
describe('inherited Values', () => {
it('should show if inherited text exists', () => {
testShowIf('{ "metadata.inherited_text": { "$exists": true }}', '<div>test</div>');
});
it('should show if inherited text has a value', () => {
testShowIf('{ "metadata.inherited_text": { "$in": ["something"] }}', '<div>test</div>');
testShowIf('{ "metadata.inherited_text": { "$nin": ["something"] }}', '');
});
it('should not show if inherited text has no specified value', () => {
testShowIf('{ "metadata.inherited_text": { "$nin": ["here"] }}', '<div>test</div>');
testShowIf('{ "metadata.inherited_text": { "$in": ["here"] }}', '');
});
});
});
59 changes: 59 additions & 0 deletions app/react/Markdown/components/specs/fixture/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Immutable from 'immutable';

const state = {
entityView: {
entity: Immutable.fromJS({
template: 't1',
title: 'Entity 1',
creationDate: 1234,
metadata: {
description: [{ value: 'A long description' }],
date: [{ value: 237600000 }],
main_image: [{ value: 'https://www.google.com' }],
inherited_text: [
{
value: '7ycel666l65vobt9',
label: 'Corte Interamericana de Derechos Humanos',
icon: null,
type: 'relationship',
inheritedValue: [
{
value: 'something',
},
],
inheritedType: 'text',
},
],
},
}),
},
templates: Immutable.fromJS([
{
_id: 't1',
commonProperties: [{ name: 'title', label: 'Title' }],
properties: [
{ name: 'description', type: 'text' },
{ name: 'date', type: 'date' },
{ name: 'main_image', label: 'Main Image', type: 'image' },
{ name: 'inherited_text', label: 'Inherited Text', type: 'relationship' },
],
},
]),
thesauris: Immutable.fromJS([{}]),
translations: Immutable.fromJS([
{
locale: 'en',
contexts: [
{
id: 't1',
values: { Title: 'Title translated', 'Main Image': 'Main Image translated' },
},
],
},
]),
settings: { collection: Immutable.fromJS({ newNameGeneration: true }) },
inlineEdit: Immutable.fromJS({ inlineEdit: false }),
locale: 'en',
};

export { state };
8 changes: 8 additions & 0 deletions app/react/Markdown/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ export const objectPath = (path, object) =>
}
return o.toJS ? o.get(key) : o[key];
}, object);

export const logError = (err, propValueOf, propLabelOf) => {
/* eslint-disable no-console */
console.error('Error on EntityData: ');
console.error('value-of: ', propValueOf, '; label-of: ', propLabelOf);
console.error(err);
/* eslint-enable no-console */
};