equipment documentation
parent
d3fa6781cc
commit
fdae12fc88
|
@ -11,7 +11,8 @@
|
||||||
"close": "Schließen",
|
"close": "Schließen",
|
||||||
"save": "Speichern",
|
"save": "Speichern",
|
||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"confirm": "Bestätigen"
|
"confirm": "Bestätigen",
|
||||||
|
"create": "Erstellen"
|
||||||
},
|
},
|
||||||
"contactAdmin": "Bitte kontaktieren Sie einen Administrator"
|
"contactAdmin": "Bitte kontaktieren Sie einen Administrator"
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"confirm": "Confirm"
|
"confirm": "Confirm",
|
||||||
|
"create": "Create"
|
||||||
},
|
},
|
||||||
"contactAdmin": "Please contact an administrator"
|
"contactAdmin": "Please contact an administrator"
|
||||||
},
|
},
|
||||||
|
|
|
@ -54,7 +54,7 @@ export default function AppRoutes() {
|
||||||
<Route
|
<Route
|
||||||
path={
|
path={
|
||||||
Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_CREATE +
|
Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_CREATE +
|
||||||
":paramEquipmentId"
|
":paramStockItemId"
|
||||||
}
|
}
|
||||||
element={<EquipmentDocumentation isEquipmentCreateModalOpen={true} />}
|
element={<EquipmentDocumentation isEquipmentCreateModalOpen={true} />}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -103,3 +103,29 @@ export function MyModalOnlyCloseButtonFooter({ onCancel }) {
|
||||||
|
|
||||||
return <Button onClick={onCancel}>{t("common.button.close")}</Button>;
|
return <Button onClick={onCancel}>{t("common.button.close")}</Button>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function MyModalCloseSaveButtonFooter({ onCancel, onSave }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button onClick={onCancel}>{t("common.button.close")}</Button>
|
||||||
|
<Button onClick={onSave} type="primary">
|
||||||
|
{t("common.button.save")}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MyModalCloseCreateButtonFooter({ onCancel, onCreate }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button onClick={onCancel}>{t("common.button.close")}</Button>
|
||||||
|
<Button onClick={onCreate} type="primary">
|
||||||
|
{t("common.button.create")}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,61 +1,96 @@
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import MyModal from "../../Components/MyModal";
|
import MyModal, {
|
||||||
import { AppStyle, Constants } from "../../utils";
|
MyModalCloseCreateButtonFooter,
|
||||||
import {
|
MyModalCloseSaveButtonFooter,
|
||||||
Button,
|
} from "../../Components/MyModal";
|
||||||
Card,
|
import { AppStyle, Constants, myFetch, myFetchContentType } from "../../utils";
|
||||||
Col,
|
import { Button, Card, Col, Row, Select, Typography } from "antd";
|
||||||
Divider,
|
import { createRef, useRef, useState } from "react";
|
||||||
Modal,
|
|
||||||
Row,
|
|
||||||
Typography,
|
|
||||||
Upload,
|
|
||||||
message,
|
|
||||||
} from "antd";
|
|
||||||
import { useRef, useState } from "react";
|
|
||||||
import TextArea from "antd/es/input/TextArea";
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import Webcam from "react-webcam";
|
import Webcam from "react-webcam";
|
||||||
import { CameraOutlined, PlusOutlined } from "@ant-design/icons";
|
import {
|
||||||
|
CameraOutlined,
|
||||||
|
DeleteOutlined,
|
||||||
|
FullscreenOutlined,
|
||||||
|
PlusOutlined,
|
||||||
|
} from "@ant-design/icons";
|
||||||
|
import { DocumentationImage } from ".";
|
||||||
|
|
||||||
const CameraComponent = () => {
|
function UploadComponent({ index, setImagePreview }) {
|
||||||
const [visible, setVisible] = useState(false);
|
const handleFileChange = (event) => {
|
||||||
const [imageData, setImageData] = useState(null);
|
const file = event.target.files[0];
|
||||||
const webcamRef = useRef();
|
console.log("file", event.target.files);
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => {
|
||||||
|
//setImagePreview(URL.createObjectURL(file));
|
||||||
|
setImagePreview(reader.result);
|
||||||
|
|
||||||
const handleCapture = () => {
|
// base 64 string
|
||||||
const imageSrc = webcamRef.current.getScreenshot();
|
// console.log(reader.result);
|
||||||
setImageData(imageSrc);
|
|
||||||
};
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
const handleClear = () => {
|
}
|
||||||
setImageData(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSave = () => {
|
|
||||||
// Hier könntest du die Logik zum Speichern des Bildes implementieren.
|
|
||||||
message.success("Bild gespeichert!");
|
|
||||||
setVisible(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button onClick={() => setVisible(true)}>Kamera öffnen</Button>
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
id={`upload-input-${index}`}
|
||||||
|
style={{ display: "none" }}
|
||||||
|
onChange={handleFileChange}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor={`upload-input-${index}`}
|
||||||
|
style={{ cursor: "pointer", display: "inline-block" }}
|
||||||
|
>
|
||||||
|
<PlusOutlined />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CameraComponent({ setImagePreview }) {
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const [cameraVisible, setCameraVisible] = useState(false);
|
||||||
|
const webcamRef = useRef(null);
|
||||||
|
|
||||||
|
const handleCapture = () => {
|
||||||
|
const imageSrc = webcamRef.current.getScreenshot();
|
||||||
|
setImagePreview(imageSrc);
|
||||||
|
|
||||||
|
handleCancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
setCameraVisible(false);
|
||||||
|
// this is needed to close the camera correctly
|
||||||
|
setTimeout(() => setModalVisible(false), 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setModalVisible(true);
|
||||||
|
setCameraVisible(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CameraOutlined />
|
||||||
|
</div>
|
||||||
|
|
||||||
<MyModal
|
<MyModal
|
||||||
title="Kamera"
|
isOpen={modalVisible}
|
||||||
isOpen={visible}
|
onCancel={handleCancel}
|
||||||
onCancel={() => setVisible(false)}
|
|
||||||
footer={[
|
footer={[
|
||||||
<Button key="clear" onClick={handleClear}>
|
<Button key={0} block type="primary" onClick={handleCapture}>
|
||||||
Löschen
|
Take picture
|
||||||
</Button>,
|
|
||||||
<Button key="capture" type="primary" onClick={handleCapture}>
|
|
||||||
Foto aufnehmen
|
|
||||||
</Button>,
|
|
||||||
<Button key="save" type="primary" onClick={handleSave}>
|
|
||||||
Speichern
|
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
{cameraVisible && (
|
||||||
<Webcam
|
<Webcam
|
||||||
audio={false}
|
audio={false}
|
||||||
ref={webcamRef}
|
ref={webcamRef}
|
||||||
|
@ -64,32 +99,143 @@ const CameraComponent = () => {
|
||||||
videoConstraints={{
|
videoConstraints={{
|
||||||
width: 1920,
|
width: 1920,
|
||||||
height: 1080,
|
height: 1080,
|
||||||
facingMode: { exact: "environment" },
|
//facingMode: { exact: "environment" },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{imageData && (
|
|
||||||
<div>
|
|
||||||
<img src={imageData} alt="Vorschau" />
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</MyModal>
|
</MyModal>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export function NoteComponent({
|
||||||
|
viewMode,
|
||||||
|
index,
|
||||||
|
image,
|
||||||
|
onImageChange,
|
||||||
|
description,
|
||||||
|
onDescriptionChange,
|
||||||
|
onDeleteImage,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Row
|
||||||
|
gutter={AppStyle.grid.row.glutter}
|
||||||
|
style={{ marginBottom: AppStyle.app.marginBottom }}
|
||||||
|
>
|
||||||
|
<Col xs={24} md={8}>
|
||||||
|
<Card
|
||||||
|
bodyStyle={{ padding: 0 }}
|
||||||
|
actions={
|
||||||
|
viewMode
|
||||||
|
? [<FullscreenOutlined />]
|
||||||
|
: [
|
||||||
|
<UploadComponent
|
||||||
|
index={index}
|
||||||
|
setImagePreview={onImageChange}
|
||||||
|
/>,
|
||||||
|
<CameraComponent setImagePreview={onImageChange} />,
|
||||||
|
<DeleteOutlined onClick={onDeleteImage} />,
|
||||||
|
<FullscreenOutlined />,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<DocumentationImage
|
||||||
|
image={image}
|
||||||
|
imgStyle={{ borderTopLeftRadius: 6, borderTopRightRadius: 6 }}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col xs={24} md={16}>
|
||||||
|
{viewMode ? (
|
||||||
|
<Typography.Text>{description}</Typography.Text>
|
||||||
|
) : (
|
||||||
|
<TextArea
|
||||||
|
rows={8}
|
||||||
|
placeholder="Description"
|
||||||
|
value={description}
|
||||||
|
onChange={onDescriptionChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const emptyNote = { image: null, description: "" };
|
||||||
|
|
||||||
|
const selectDocumentationTypeOptions = [
|
||||||
|
{ value: 0, label: "Repair protocol" },
|
||||||
|
{ value: 1, label: "Documentation" },
|
||||||
|
];
|
||||||
|
|
||||||
export default function CreateEquipmentDocumentationModal({ isOpen }) {
|
export default function CreateEquipmentDocumentationModal({ isOpen }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
let { paramEquipmentId } = useParams();
|
let { paramStockItemId } = useParams();
|
||||||
|
|
||||||
const [title, setTitle] = useState("");
|
const [title, setTitle] = useState("New documentation");
|
||||||
|
const [selectedDocumentationType, setSelectedDocumentationType] = useState(
|
||||||
|
selectDocumentationTypeOptions[0].value
|
||||||
|
);
|
||||||
|
const [notes, setNotes] = useState([emptyNote]);
|
||||||
|
|
||||||
const handleCancel = () =>
|
const handleCancel = () =>
|
||||||
navigate(Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION);
|
navigate(Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION);
|
||||||
|
|
||||||
console.log("paramEquipmentId", paramEquipmentId);
|
const handleCreate = () => {
|
||||||
|
let obj = {
|
||||||
|
stockItemId: paramStockItemId,
|
||||||
|
type: selectedDocumentationType,
|
||||||
|
title: title,
|
||||||
|
notes: notes,
|
||||||
|
};
|
||||||
|
|
||||||
|
myFetch(`/equipment/documentation/create`, "POST", obj, {}).then((data) => {
|
||||||
|
console.log("data", data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDescriptionChange = (index) => (e) => {
|
||||||
|
const updatedNotes = [...notes];
|
||||||
|
|
||||||
|
updatedNotes[index] = {
|
||||||
|
...updatedNotes[index],
|
||||||
|
description: e.target.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
setNotes(updatedNotes);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImageChange = (index) => (newImage) => {
|
||||||
|
const updatedNotes = [...notes];
|
||||||
|
|
||||||
|
updatedNotes[index] = {
|
||||||
|
...updatedNotes[index],
|
||||||
|
image: newImage,
|
||||||
|
};
|
||||||
|
|
||||||
|
setNotes(updatedNotes);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddNote = () => setNotes([...notes, emptyNote]);
|
||||||
|
|
||||||
|
const isAddNoteButtonDisabled = () => {
|
||||||
|
const lastNote = notes[notes.length - 1];
|
||||||
|
|
||||||
|
return lastNote.image === null && lastNote.description === "";
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen={isOpen} onCancel={handleCancel}>
|
<MyModal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
footer={
|
||||||
|
<MyModalCloseCreateButtonFooter
|
||||||
|
onCreate={handleCreate}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
<Typography.Title
|
<Typography.Title
|
||||||
editable={{ text: title, onChange: setTitle }}
|
editable={{ text: title, onChange: setTitle }}
|
||||||
level={1}
|
level={1}
|
||||||
|
@ -97,46 +243,39 @@ export default function CreateEquipmentDocumentationModal({ isOpen }) {
|
||||||
{title}
|
{title}
|
||||||
</Typography.Title>
|
</Typography.Title>
|
||||||
|
|
||||||
<Row gutter={AppStyle.grid.row.glutter}>
|
<div style={{ marginBottom: AppStyle.typography.text.marginBottom }}>
|
||||||
<Col sm={6}>
|
<Typography.Text>Documentation type</Typography.Text>
|
||||||
<Card>
|
</div>
|
||||||
<Card.Grid
|
|
||||||
hoverable={false}
|
<Select
|
||||||
style={{
|
defaultValue={selectedDocumentationType}
|
||||||
width: "50%",
|
style={{ width: "100%", marginBottom: AppStyle.app.marginBottom }}
|
||||||
textAlign: "center",
|
onChange={(value) => setSelectedDocumentationType(value)}
|
||||||
borderTopLeftRadius: AppStyle.app.borderRadius,
|
options={selectDocumentationTypeOptions}
|
||||||
borderBottomLeftRadius: AppStyle.app.borderRadius,
|
/>
|
||||||
}}
|
|
||||||
onClick={() => console.log("upload")}
|
{notes.map((note, index) => (
|
||||||
|
<NoteComponent
|
||||||
|
key={index}
|
||||||
|
index={index}
|
||||||
|
image={note.image}
|
||||||
|
onImageChange={handleImageChange(index)}
|
||||||
|
description={note.description}
|
||||||
|
onDescriptionChange={handleDescriptionChange(index)}
|
||||||
|
onDeleteImage={() => handleImageChange(index)(null)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div style={{ textAlign: "center" }}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
disabled={isAddNoteButtonDisabled()}
|
||||||
|
icon={<PlusOutlined />}
|
||||||
|
onClick={handleAddNote}
|
||||||
>
|
>
|
||||||
<Upload>
|
Add note
|
||||||
<PlusOutlined />
|
</Button>
|
||||||
<p>Upload</p>
|
</div>
|
||||||
</Upload>
|
|
||||||
</Card.Grid>
|
|
||||||
|
|
||||||
<Card.Grid
|
|
||||||
hoverable={false}
|
|
||||||
style={{
|
|
||||||
width: "50%",
|
|
||||||
textAlign: "center",
|
|
||||||
borderTopRightRadius: AppStyle.app.borderRadius,
|
|
||||||
borderBottomRightRadius: AppStyle.app.borderRadius,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CameraOutlined />
|
|
||||||
<p>Take</p>
|
|
||||||
</Card.Grid>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col sm={18}>
|
|
||||||
<TextArea rows={8} placeholder="Description" />
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<CameraComponent />
|
|
||||||
</MyModal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@ import { AppStyle, Constants, myFetch } from "../../utils";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { QrScanner } from "@yudiel/react-qr-scanner";
|
import { QrScanner } from "@yudiel/react-qr-scanner";
|
||||||
import EquipmentViewModal from "./EquipmentViewModal";
|
import EquipmentViewModal from "./EquipmentViewModal";
|
||||||
import CreateEquipmentDocumentationModal from "./CreateEquipmentDocumentationModal";
|
import CreateEquipmentDocumentationModal, {
|
||||||
|
NoteComponent,
|
||||||
|
} from "./CreateEquipmentDocumentationModal";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export default function EquipmentDocumentation({ isEquipmentCreateModalOpen }) {
|
export default function EquipmentDocumentation({ isEquipmentCreateModalOpen }) {
|
||||||
|
@ -107,6 +109,36 @@ export default function EquipmentDocumentation({ isEquipmentCreateModalOpen }) {
|
||||||
}));
|
}));
|
||||||
}; */
|
}; */
|
||||||
|
|
||||||
|
const CreateDocumentationButton = () => {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
to={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_CREATE}${scannerResult}`}
|
||||||
|
>
|
||||||
|
<Button type="primary">Create documentation</Button>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DocumentationContent = ({ documentation }) => {
|
||||||
|
console.log("doc", documentation);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<Typography.Title level={4}>{documentation.Title}</Typography.Title>
|
||||||
|
|
||||||
|
{documentation.Notes !== "" &&
|
||||||
|
JSON.parse(documentation.Notes).map((note, index) => (
|
||||||
|
<NoteComponent
|
||||||
|
key={index}
|
||||||
|
viewMode
|
||||||
|
image={`${Constants.STATIC_CONTENT_ADDRESS}equipmentdocumentation/${documentation.Id}/${note.Image}`}
|
||||||
|
description={note.Description}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Row style={{ marginBottom: AppStyle.app.marginBottom }}>
|
<Row style={{ marginBottom: AppStyle.app.marginBottom }}>
|
||||||
|
@ -147,7 +179,7 @@ export default function EquipmentDocumentation({ isEquipmentCreateModalOpen }) {
|
||||||
|
|
||||||
<h1>ScannerResult: {scannerResult}</h1>
|
<h1>ScannerResult: {scannerResult}</h1>
|
||||||
|
|
||||||
{scannerResult !== "" && equipmentDocumentation.length === 0 && (
|
{scannerResult !== "" && equipmentDocumentation.length === 0 ? (
|
||||||
<Result
|
<Result
|
||||||
status="404"
|
status="404"
|
||||||
title="404"
|
title="404"
|
||||||
|
@ -158,14 +190,18 @@ export default function EquipmentDocumentation({ isEquipmentCreateModalOpen }) {
|
||||||
Back to Overview
|
Back to Overview
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Link
|
<CreateDocumentationButton />
|
||||||
to={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_CREATE}${scannerResult}`}
|
|
||||||
>
|
|
||||||
<Button type="primary">Create documentation</Button>
|
|
||||||
</Link>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<CreateDocumentationButton />
|
||||||
|
|
||||||
|
{equipmentDocumentation.map((documentation, index) => (
|
||||||
|
<DocumentationContent key={index} documentation={documentation} />
|
||||||
|
))}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<CreateEquipmentDocumentationModal isOpen={isEquipmentCreateModalOpen} />
|
<CreateEquipmentDocumentationModal isOpen={isEquipmentCreateModalOpen} />
|
||||||
|
@ -173,6 +209,30 @@ export default function EquipmentDocumentation({ isEquipmentCreateModalOpen }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function DocumentationImage({ image, imgStyle }) {
|
||||||
|
return image ? (
|
||||||
|
<img
|
||||||
|
src={image}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
...imgStyle,
|
||||||
|
}}
|
||||||
|
alt="Preview"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: 250,
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
No image selected
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* <EquipmentViewModal isOpen={isEquipmentViewModalOpen} />
|
/* <EquipmentViewModal isOpen={isEquipmentViewModalOpen} />
|
||||||
<Table
|
<Table
|
||||||
loading={fetchingEquipment}
|
loading={fetchingEquipment}
|
||||||
|
|
41
src/utils.js
41
src/utils.js
|
@ -130,6 +130,11 @@ export const AppStyle = {
|
||||||
marginBottom: 12,
|
marginBottom: 12,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
},
|
},
|
||||||
|
typography: {
|
||||||
|
text: {
|
||||||
|
marginBottom: 6,
|
||||||
|
},
|
||||||
|
},
|
||||||
grid: {
|
grid: {
|
||||||
row: {
|
row: {
|
||||||
glutter: [16, 16],
|
glutter: [16, 16],
|
||||||
|
@ -1299,16 +1304,40 @@ export function DecodedBase64ToString(value) {
|
||||||
return Buffer.from(value, "base64").toString();
|
return Buffer.from(value, "base64").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const myFetchDefaultHeaders = {
|
export const myFetchContentType = {
|
||||||
"Content-Type": "application/json",
|
JSON: 0,
|
||||||
"X-Authorization": getUserSessionFromLocalStorage(),
|
MULTIPART_FORM_DATA: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function myFetch(
|
||||||
|
url,
|
||||||
|
method,
|
||||||
|
body = null,
|
||||||
|
headers = {},
|
||||||
|
contentType = myFetchContentType.JSON
|
||||||
|
) {
|
||||||
|
const getContentType = () => {
|
||||||
|
if (contentType === myFetchContentType.JSON) return "application/json";
|
||||||
|
|
||||||
|
return "multipart/form-data";
|
||||||
|
};
|
||||||
|
|
||||||
|
const getBody = () => {
|
||||||
|
if (!body) return null;
|
||||||
|
|
||||||
|
if (contentType === myFetchContentType.JSON) return JSON.stringify(body);
|
||||||
|
|
||||||
|
return body;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function myFetch(url, method, body = null, headers = {}) {
|
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: method,
|
method: method,
|
||||||
headers: { ...myFetchDefaultHeaders, ...headers },
|
headers: {
|
||||||
body: body ? JSON.stringify(body) : null,
|
"X-Authorization": getUserSessionFromLocalStorage(),
|
||||||
|
"Content-Type": getContentType(),
|
||||||
|
...headers,
|
||||||
|
},
|
||||||
|
body: getBody(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return fetch(`${Constants.API_ADDRESS}${url}`, requestOptions)
|
return fetch(`${Constants.API_ADDRESS}${url}`, requestOptions)
|
||||||
|
|
Loading…
Reference in New Issue