Skip to content

Commit

Permalink
Merge pull request #120 from akvo/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
dedenbangkit authored May 11, 2023
2 parents f681395 + 0e7889a commit 0fa52f5
Show file tree
Hide file tree
Showing 21 changed files with 1,525 additions and 569 deletions.
802 changes: 565 additions & 237 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

804 changes: 566 additions & 238 deletions dist/index.modern.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.modern.js.map

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions example/src/example-initial-value.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,10 @@
"question": 28,
"repeatIndex": 1,
"value": [106]
},
{
"question": 29,
"repeatIndex": 0,
"value": "https://fastly.picsum.photos/id/528/200/300.jpg?hmac=nQ5klrDwddW0du03zqKfOpyHkFBDaspI729AfK_FXPY"
}
]
19 changes: 19 additions & 0 deletions example/src/example.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,25 @@
"language": "id"
}
]
},
{
"id": 29,
"name": "Upload photo",
"order": 9,
"type": "image",
"required": true,
"tooltip": {
"text": "Image for profile photo",
"translations": [
{
"text": "Gambar untuk foto profil",
"language": "id"
}
]
},
"meta": false,
"requiredSign": "**",
"limit": 2
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "akvo-react-form",
"version": "2.2.0",
"version": "2.2.1",
"description": "Simple react component for building webforms",
"license": "AGPL-3.0",
"repository": "akvo/akvo-react-form",
Expand Down
14 changes: 14 additions & 0 deletions src/components/QuestionFields.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
TypeGeo,
TypeAutoField,
TypeTable,
TypeImage,
} from '../fields';

const QuestionFields = ({
Expand Down Expand Up @@ -94,6 +95,7 @@ const QuestionFields = ({
<TypeText
keyform={index}
rules={rules}
uiText={uiText}
{...field}
/>
);
Expand All @@ -102,6 +104,7 @@ const QuestionFields = ({
<TypeAutoField
keyform={index}
rules={rules}
uiText={uiText}
{...field}
/>
);
Expand All @@ -114,11 +117,22 @@ const QuestionFields = ({
{...field}
/>
);
case 'image':
return (
<TypeImage
keyform={index}
rules={rules}
initialValue={initialValue}
uiText={uiText}
{...field}
/>
);
default:
return (
<TypeInput
keyform={index}
rules={rules}
uiText={uiText}
{...field}
/>
);
Expand Down
163 changes: 163 additions & 0 deletions src/fields/TypeImage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React, { useState, useEffect } from 'react';
import { Col, Form, Input, Upload, message } from 'antd';
import { FieldLabel } from '../support';
import DraggerText from '../support/DraggerText';
import ImagePreview from '../support/ImagePreview';

const { Dragger } = Upload;

const FILE_TYPES = ['image/png', 'image/jpeg', 'image/jpg'];

const getImageBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const base64String = reader.result;
resolve(base64String);
};
reader.onerror = (error) => {
reject(error);
};
});
};

const convertImageToBase64 = (imgUrl) => {
return new Promise((resolve, reject) => {
const image = new Image();
image.crossOrigin = 'anonymous';
image.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.height = image.naturalHeight;
canvas.width = image.naturalWidth;
ctx.drawImage(image, 0, 0);
const dataUrl = canvas.toDataURL();
resolve(dataUrl);
};
image.src = imgUrl;
image.onerror = (error) => {
reject(error);
};
});
};

const TypeImage = ({
id,
name,
keyform,
required,
rules,
tooltip,
requiredSign,
initialValue = null,
limit = 2,
}) => {
const [fileList, setFileList] = useState([]);
const [preview, setPreview] = useState(null);
const [visible, setVisible] = useState(false);
const form = Form.useFormInstance();

useEffect(() => {
if (initialValue && fileList.length === 0) {
convertImageToBase64(initialValue).then((initialBase64) => {
form.setFieldsValue({ [id]: initialBase64 });
});

setFileList([
{
uid: '1',
status: 'done',
name: initialValue,
url: initialValue,
},
]);
}
}, [initialValue, fileList]);

const fileListExists = fileList.filter((f) => f?.status !== 'removed');
return (
<Col>
<Form.Item
className="arf-field"
label={
<FieldLabel
keyform={keyform}
content={name}
requiredSign={required ? requiredSign : null}
/>
}
tooltip={tooltip?.text}
required={required}
>
<Form.Item
className="arf-field-image"
name={id}
rules={rules}
required={required}
noStyle
>
<Input
disabled
hidden
/>
</Form.Item>
<Dragger
multiple={false}
listType="picture"
fileList={fileListExists}
customRequest={({ onSuccess }) => {
onSuccess('ok');
}}
beforeUpload={(file) => {
const fileMB = file.size / (1024 * 1024);
const validate = fileMB <= limit && FILE_TYPES.includes(file.type);
if (validate) {
setFileList([
{
...file,
name: file.name,
url: URL.createObjectURL(file),
},
]);
}
if (!validate) {
setFileList([]);
message.error(
`File size exceeds the limit. Please upload a file smaller than ${limit} MB.`
);
}
return validate;
}}
onChange={({ file: { status, originFileObj } }) => {
if (fileList.length) {
setFileList([
{
...fileList[0],
status,
},
]);
}
if (originFileObj && (status === 'success' || status === 'done')) {
getImageBase64(originFileObj).then((imageBase64String) => {
form.setFieldsValue({ [id]: imageBase64String });
});
}
}}
onPreview={({ url }) => {
setPreview(url);
setVisible(true);
}}
>
<DraggerText limit={limit} />
</Dragger>
<ImagePreview
visible={visible}
src={preview}
onChange={setVisible}
/>
</Form.Item>
</Col>
);
};
export default TypeImage;
1 change: 1 addition & 0 deletions src/fields/TypeTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const TypeTable = ({
extra,
columns,
requiredSign,
uiText,
}) => {
const form = Form.useFormInstance();
const initialData = form.getFieldValue(id);
Expand Down
1 change: 1 addition & 0 deletions src/fields/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export { default as TypeText } from './TypeText';
export { default as TypeTree } from './TypeTree';
export { default as TypeAutoField } from './TypeAutoField';
export { default as TypeTable } from './TypeTable';
export { default as TypeImage } from './TypeImage';
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ export const Webform = ({
);

useEffect(() => {
// initial value load: related to src/lib/db.js line 95
form.resetFields();
if (initialValue.length) {
setLoadingInitial(true);
Expand Down
17 changes: 11 additions & 6 deletions src/lib/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const getId = (name) => {
});
};

const getValue = ({ dataId, questionId = null }) => {
const getValue = ({ dataId, questionId = null, updateGlobalStore = false }) => {
if (questionId) {
const question = getQuestionDetail(questionId);
return db.values
Expand Down Expand Up @@ -92,10 +92,15 @@ const getValue = ({ dataId, questionId = null }) => {
repeatIndex: q.repeat,
value: JSON.parse(q.value),
}));
GlobalStore.update((s) => {
s.initialValue = data;
s.isLeftDrawerVisible = false;
});
if (updateGlobalStore) {
// don't update global state every getValue func used
// that's caused initial value reset / not loaded properly
// related to src/index.js line 346
GlobalStore.update((s) => {
s.initialValue = data;
s.isLeftDrawerVisible = false;
});
}
resolve(data);
});
})
Expand Down Expand Up @@ -202,7 +207,7 @@ const listData = (formId) => {
resolve(
values.map((v) => ({
...v,
load: () => getValue({ dataId: v.id }),
load: () => getValue({ dataId: v.id, updateGlobalStore: true }),
remove: () => deleteData(v.id),
}))
);
Expand Down
38 changes: 23 additions & 15 deletions src/locale/de.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
{
"submit": "Absenden",
"add": "Weitere",
"addAnother": "Weitere hinzufügen",
"cancel": "Stornieren",
"delete": "Löschen",
"download": "Herunterladen",
"save": "Speichern",
"print": "Drucken",
"edit": "Bearbeiten",
"errorDecimal": "Dezimalwerte sind für diese Frage nicht erlaubt",
"errorIsRequired": "ist erforderlich",
"errorMax": "Der Wert muss kleiner oder gleich sein als",
"errorMin": "Der Wert muss größer oder gleich sein als",
"errorMinMax": "Der Wert muss zwischen liegen",
"formOverview": "Formularübersicht",
"loadingInitialData": "Lade Initialdaten",
"submissionSaved": "Einreichung gespeichert",
"addAnother": "Weitere hinzufügen",
"selectLevel": "Level auswählen",
"selectDate": "Datum auswählen",
"pleaseSelect": "Bitte auswählen",
"ok": "ok",
"pleaseEnterItem": "Bitte geben Sie den Artikel ein",
"pleaseInput": "Bitte eingeben",
"pleaseSelect": "Bitte auswählen",
"pleaseTypeOtherOption": "Bitte geben Sie eine andere Option ein",
"pleaseEnterItem": "Bitte geben Sie den Artikel ein",
"useMyLocation": "Meinen Standort verwenden",
"errorIsRequired": "ist erforderlich",
"errorDecimal": "Dezimalwerte sind für diese Frage nicht erlaubt",
"errorMin": "Der Wert muss größer oder gleich sein als",
"errorMax": "Der Wert muss kleiner oder gleich sein als",
"errorMinMax": "Der Wert muss zwischen liegen"
"print": "Drucken",
"remove": "Entfernen",
"save": "Speichern",
"selectDate": "Datum auswählen",
"selectLevel": "Level auswählen",
"submissionSaved": "Einreichung gespeichert",
"submit": "Absenden",
"sureToCancel": "Sicher absagen?",
"sureToDelete": "Sicher löschen?",
"useMyLocation": "Meinen Standort verwenden"
}
Loading

0 comments on commit 0fa52f5

Please sign in to comment.