Skip to content

Commit

Permalink
fix: use form field plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
eirikhaugstulen committed Jan 9, 2024
1 parent 433afa5 commit e1e6b1f
Show file tree
Hide file tree
Showing 11 changed files with 3,628 additions and 2,419 deletions.
13 changes: 5 additions & 8 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2023-09-12T06:24:49.265Z\n"
"PO-Revision-Date: 2023-09-12T06:24:49.265Z\n"
"POT-Creation-Date: 2024-01-09T13:38:29.984Z\n"
"PO-Revision-Date: 2024-01-09T13:38:29.984Z\n"

msgid "Choose one or more dates..."
msgstr "Choose one or more dates..."
Expand Down Expand Up @@ -71,9 +71,6 @@ msgstr "error encountered during field validation"
msgid "error"
msgstr "error"

msgid "Plugins are not yet available - Please contact your system administrator"
msgstr "Plugins are not yet available - Please contact your system administrator"

msgid "This value is validating"
msgstr "This value is validating"

Expand Down Expand Up @@ -1380,6 +1377,9 @@ msgstr "This stage can only have one event"
msgid "Events could not be retrieved. Please try again later."
msgstr "Events could not be retrieved. Please try again later."

msgid "Assigned to"
msgstr "Assigned to"

msgid "{{ totalEvents }} events"
msgstr "{{ totalEvents }} events"

Expand Down Expand Up @@ -1446,9 +1446,6 @@ msgstr "Download data..."
msgid "an error occurred loading working lists"
msgstr "an error occurred loading working lists"

msgid "Assigned to"
msgstr "Assigned to"

msgid "Registration Date"
msgstr "Registration Date"

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"@babel/preset-react": "^7.16.7",
"@badeball/cypress-cucumber-preprocessor": "17.2.1",
"@cypress/webpack-preprocessor": "^6.0.0",
"@dhis2/cli-app-scripts": "^9.0.1",
"@dhis2/cli-app-scripts": "^10.4.0",
"@dhis2/cli-helpers-engine": "^3.2.1",
"@dhis2/cli-style": "^10.4.1",
"@dhis2/cli-utils-cypress": "^9.0.2",
Expand Down Expand Up @@ -132,6 +132,9 @@
"wait-on": "^6.0.1"
},
"resolutions": {
"@dhis2/cli-app-scripts": "^10.4.0",
"@dhis2/app-runtime": "^3.10.2",
"react-scripts": "4.0.3",
"@babel/preset-react": "7.16.7",
"@js-temporal/polyfill": "0.4.3",
"core-js": "2.5.7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,11 @@ export class D2SectionFieldsComponent extends Component<Props> {
component: FormFieldPlugin,
plugin: true,
props: {
pluginId: metaDataElement.id,
name: metaDataElement.name,
pluginSource: metaDataElement.pluginSource,
fieldsMetadata: metaDataElement.fields,
customAttributes: metaDataElement.customAttributes,
formId: props.formId,
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,17 +537,21 @@ export class FormBuilder extends React.Component<Props> {
pluginContext,
} = this.props;
const {
fieldsMetadata,
pluginId,
pluginSource,
fieldsMetadata,
customAttributes,
name,
formId,
} = field.props;

return (
<field.component
name={name}
fieldsMetadata={fieldsMetadata}
pluginId={pluginId}
customAttributes={customAttributes}
pluginSource={pluginSource}
fieldsMetadata={fieldsMetadata}
formId={formId}
onUpdateField={this.commitFieldUpdateFromPlugin.bind(this)}
pluginContext={pluginContext}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
// @flow
import React from 'react';
import i18n from '@dhis2/d2-i18n';
import React, { useEffect, useRef, useState } from 'react';
import { Plugin } from '@dhis2/app-runtime/build/es/experimental';
import type { ComponentProps } from './FormFieldPlugin.types';

export const FormFieldPluginComponent = (props: ComponentProps) => {
// eslint-disable-next-line no-unused-vars
const { pluginSource, ...passOnProps } = props;
const containerRef = useRef<?HTMLDivElement>(null);
const [pluginWidth, setPluginWidth] = useState(0);

useEffect(() => {
const { current: container } = containerRef;
if (!container) return;

const resizeObserver = new ResizeObserver((entries) => {
entries.forEach(entry => setPluginWidth(entry.contentRect.width));
});

resizeObserver.observe(container);

// Cleanup function
// eslint-disable-next-line consistent-return
return () => {
resizeObserver.unobserve(container);
resizeObserver.disconnect();
};
}, [containerRef]);


return (
<p>
{i18n.t('Plugins are not yet available - Please contact your system administrator')}
</p>
<div ref={containerRef}>
<Plugin
pluginSource={pluginSource}
width={pluginWidth}
{...passOnProps}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import React, { useEffect, useMemo } from 'react';
import React, { useMemo } from 'react';
import { FormFieldPluginComponent } from './FormFieldPlugin.component';
import type { ContainerProps } from './FormFieldPlugin.types';
import { usePluginMessages } from './hooks/usePluginMessages';
Expand All @@ -9,7 +9,14 @@ import { formatPluginConfig } from './formatPluginConfig';
import { useLocationQuery } from '../../../utils/routing';

export const FormFieldPlugin = (props: ContainerProps) => {
const { pluginSource, fieldsMetadata, formId, onUpdateField, pluginContext } = props;
const {
pluginSource,
fieldsMetadata,
formId,
onUpdateField,
customAttributes,
pluginContext,
} = props;
const metadataByPluginId = useMemo(() => Object.fromEntries(fieldsMetadata), [fieldsMetadata]);
const configuredPluginIds = useMemo(() => Object.keys(metadataByPluginId), [metadataByPluginId]);
const { orgUnitId } = useLocationQuery();
Expand All @@ -24,20 +31,18 @@ export const FormFieldPlugin = (props: ContainerProps) => {
pluginContext,
});

// Expanding iframe height temporarily to fit content - LIBS-487
useEffect(() => {
const iframe = document.querySelector('iframe');
if (iframe) iframe.style.height = '500px';
}, []);

// Remove ids from plugin metadata before passing to plugin
const formattedMetadata = useMemo(() => {
const metadata = [...fieldsMetadata.entries()];
return metadata.reduce((acc, [pluginId, pluginMetadata]) => {
const formattedPluginMetadata = formatPluginConfig(pluginMetadata, { keysToOmit: ['id'] });
return { ...acc, [pluginId]: formattedPluginMetadata };

return metadata.reduce((acc, [pluginFieldId, pluginMetadata]) => {
const formattedPluginMetadata = formatPluginConfig(pluginMetadata, {
attributes: customAttributes,
keysToOmit: ['id', 'dataElement', 'section'],
});
return { ...acc, [pluginFieldId]: formattedPluginMetadata };
}, {});
}, [fieldsMetadata]);
}, [customAttributes, fieldsMetadata]);

return (
<FormFieldPluginComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type PluginFormFieldMetadata = {|
searchable: ?boolean;
url: ?string;
attributeValues?: { [pluginId: string]: any }

|}

type FieldValueOptions = {|
Expand All @@ -45,10 +46,12 @@ export type PluginContext = {|
|}

export type ContainerProps = {|
pluginId: string,
pluginSource: string,
fieldsMetadata: Map<string, PluginFormFieldMetadata>,
pluginContext: PluginContext,
formId: string,
customAttributes: { [id: string]: { IdFromPlugin: string, IdFromApp: string } },
onUpdateField: (fieldMetadata: PluginFormFieldMetadata, value: any, options?: FieldValueOptions) => void,
|}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@ export const formatPluginConfig = <TConfigReturn = PluginFormFieldMetadata>(
}

// Recursively process nested objects and arrays
if (value && typeof value === 'object') {
if (Array.isArray(value)) {
acc[modifiedKey] = value.map(removeUnderscoreFromObjectAttributes).filter(Boolean);
if (value !== null) {
if (typeof value === 'object') {
if (Array.isArray(value)) {
acc[modifiedKey] = value.map(removeUnderscoreFromObjectAttributes)
.filter(Boolean);
} else {
acc[modifiedKey] = removeUnderscoreFromObjectAttributes(value);
}
} else {
acc[modifiedKey] = removeUnderscoreFromObjectAttributes(value);
acc[modifiedKey] = value;
}
} else {
acc[modifiedKey] = value;
}

return acc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
/* eslint-disable no-restricted-syntax */

import isFunction from 'd2-utilizr/lib/isFunction';
import type { PluginFormFieldMetadata } from '../../components/D2Form/FormFieldPlugin';
import { DataElement } from '../DataElement';

export class FormFieldPluginConfig {
_id: string;
_name: string;
_pluginSource: string;
_fields: Map<string, PluginFormFieldMetadata>;
_fields: Map<string, DataElement>;
_customAttributes: Map<string, { IdFromPlugin: string, IdFromApp: string }>;

constructor(initFn: ?(_this: FormFieldPluginConfig) => void) {
initFn && isFunction(initFn) && initFn(this);
Expand All @@ -32,23 +33,31 @@ export class FormFieldPluginConfig {
this._name = value;
}

get fields(): Map<string, PluginFormFieldMetadata> {
get fields(): Map<string, DataElement> {
return this._fields;
}

set fields(value: Map<string, PluginFormFieldMetadata>) {
set fields(value: Map<string, DataElement>) {
this._fields = value;
}

get pluginSource(): string {
return this._pluginSource;
}

get customAttributes(): Map<string, { IdFromPlugin: string, IdFromApp: string }> {
return this._customAttributes;
}

set customAttributes(value: Map<string, { IdFromPlugin: string, IdFromApp: string }>) {
this._customAttributes = value;
}

set pluginSource(value: string) {
this._pluginSource = value;
}

addField(idFromPlugin: string, field: PluginFormFieldMetadata) {
addField(idFromPlugin: string, field: DataElement) {
if (!this.fields.has(idFromPlugin)) {
this.fields.set(idFromPlugin, field);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ import { transformTrackerNode } from '../transformNodeFuntions/transformNodeFunc
import { FormFieldPluginConfig } from '../../../../metaData/FormFieldPluginConfig';
import type { DataEntryFormConfig } from '../../../../components/DataEntries/common/TEIAndEnrollment/useMetadataForRegistrationForm/types';
import { FormFieldTypes } from '../../../../components/D2Form/FormFieldPlugin/FormFieldPlugin.const';
import {
formatPluginConfig,
} from '../../../../components/D2Form/FormFieldPlugin/formatPluginConfig';

export class EnrollmentFactory {
static errorMessages = {
Expand Down Expand Up @@ -141,28 +138,27 @@ export class EnrollmentFactory {
// $FlowFixMe
await cachedProgramTrackedEntityAttributes.asyncForEach(async (trackedEntityAttribute) => {
if (trackedEntityAttribute?.type === FormFieldTypes.PLUGIN) {
const element = new FormFieldPluginConfig((o) => {
o.id = trackedEntityAttribute.id;
o.name = trackedEntityAttribute.name;
o.pluginSource = trackedEntityAttribute.pluginSource;
o.fields = new Map();
});

const attributes = trackedEntityAttribute.fieldMap
.filter(attributeField => attributeField.objectType === 'Attribute')
.reduce((acc, attribute) => {
acc[attribute.IdFromApp] = attribute;
return acc;
}, {});

const element = new FormFieldPluginConfig((o) => {
o.id = trackedEntityAttribute.id;
o.name = trackedEntityAttribute.name;
o.pluginSource = trackedEntityAttribute.pluginSource;
o.fields = new Map();
o.customAttributes = attributes;
});

await trackedEntityAttribute.fieldMap.asyncForEach(async (field) => {
if (field.objectType) {
const fieldElement = await this.dataElementFactory.build(field);
if (field.objectType && field.objectType === 'dataElement') {
const fieldElement = await this.dataElementFactory.build(field, section);
if (!fieldElement) return;

const fieldMetadata = formatPluginConfig(fieldElement, { attributes });

element.addField(field.IdFromPlugin, fieldMetadata);
element.addField(field.IdFromPlugin, fieldElement);
}
});

Expand Down
Loading

0 comments on commit e1e6b1f

Please sign in to comment.