datasync-blob 1.1.32 → 1.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DsBlob.d.ts +48 -0
- package/dist/components/DsBlob.js +421 -490
- package/package.json +16 -21
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
interface ErrorObject {
|
|
2
|
+
error_code: string;
|
|
3
|
+
error_definition: string;
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
interface UploadFile {
|
|
7
|
+
data: string;
|
|
8
|
+
cloud_url_prefix?: string;
|
|
9
|
+
isBlobUrl?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface DsBlobProps {
|
|
12
|
+
/** Field identifier (used by datasync-dynamic-form) */
|
|
13
|
+
item_id?: string;
|
|
14
|
+
/** Current image data: base64 data-URL, cloud URL, or blob URL */
|
|
15
|
+
data?: string;
|
|
16
|
+
binaryData?: ArrayBuffer | null;
|
|
17
|
+
/** Callback fired after every image change */
|
|
18
|
+
uploadPicture: (uploadFile: UploadFile) => void;
|
|
19
|
+
/** Exact pixel size constraints */
|
|
20
|
+
width?: number;
|
|
21
|
+
height?: number;
|
|
22
|
+
/** Maximum pixel size constraints (used with reduceImage) */
|
|
23
|
+
maxWidth?: number;
|
|
24
|
+
maxHeight?: number;
|
|
25
|
+
/** Maximum file size in kilobytes */
|
|
26
|
+
maxKBytes?: number;
|
|
27
|
+
/** Automatically downscale oversized images instead of rejecting them */
|
|
28
|
+
reduceImage?: boolean;
|
|
29
|
+
/** JPEG quality 0–1 (default 1 = lossless) */
|
|
30
|
+
jpegQuality?: number;
|
|
31
|
+
/** Upload image to Datasync cloud storage instead of encoding as base64 */
|
|
32
|
+
cloud_storage?: boolean;
|
|
33
|
+
cloud_url_prefix?: string;
|
|
34
|
+
/** Label shown on the upload button */
|
|
35
|
+
Caption?: string;
|
|
36
|
+
/** CSS class applied to the upload button */
|
|
37
|
+
buttonStyle?: string;
|
|
38
|
+
/** CSS class applied to the displayed image */
|
|
39
|
+
pictureStyle?: string;
|
|
40
|
+
readOnly?: boolean;
|
|
41
|
+
isCloudUrl?: boolean;
|
|
42
|
+
isBlobUrl?: boolean;
|
|
43
|
+
/** Called when a validation error occurs (size, dimensions, format) */
|
|
44
|
+
onErrorHandler?: (errorObject: ErrorObject) => void;
|
|
45
|
+
debugging?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare function DsBlob(props: DsBlobProps): JSX.Element;
|
|
48
|
+
export {};
|
|
@@ -1,509 +1,440 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
5
17
|
});
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.state = {
|
|
15
|
-
hover_input: false,
|
|
16
|
-
hover_image: false,
|
|
17
|
-
data: props.data || "",
|
|
18
|
-
binaryData: props.binaryData || null
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
19
26
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let binaryStr = '';
|
|
66
|
-
const chunkSize = 8192;
|
|
67
|
-
for (let i = 0; i < uint8Array.length; i += chunkSize) {
|
|
68
|
-
const chunk = uint8Array.slice(i, i + chunkSize);
|
|
69
|
-
binaryStr += String.fromCharCode(...chunk);
|
|
70
|
-
}
|
|
71
|
-
binaryString = btoa(binaryStr);
|
|
72
|
-
} else if (pictureBlob.binaryData instanceof Uint8Array) {
|
|
73
|
-
// Already a Uint8Array, convert to base64
|
|
74
|
-
let binaryStr = '';
|
|
75
|
-
const chunkSize = 8192;
|
|
76
|
-
for (let i = 0; i < pictureBlob.binaryData.length; i += chunkSize) {
|
|
77
|
-
const chunk = pictureBlob.binaryData.slice(i, i + chunkSize);
|
|
78
|
-
binaryStr += String.fromCharCode(...chunk);
|
|
79
|
-
}
|
|
80
|
-
binaryString = btoa(binaryStr);
|
|
81
|
-
} else {
|
|
82
|
-
// Assume it's already a string
|
|
83
|
-
binaryString = pictureBlob.binaryData || "";
|
|
84
|
-
}
|
|
85
|
-
formData.append('binary', binaryString);
|
|
86
|
-
console.log("binaryString ->", binaryString.substring(0, 100) + '...'); // Log the beginning of the base64 string for debugging
|
|
87
|
-
|
|
88
|
-
const results = await fetch('http://localhost:8888/datasync-service/Sync.php', {
|
|
89
|
-
method: 'POST',
|
|
90
|
-
body: formData
|
|
91
|
-
});
|
|
92
|
-
if (!results.ok) {
|
|
93
|
-
throw new Error(`HTTP error! status: ${response.statusText}`);
|
|
94
|
-
}
|
|
95
|
-
let sync_push_cloud_response = await results.json();
|
|
96
|
-
|
|
97
|
-
// Try to parse as JSON
|
|
98
|
-
try {
|
|
99
|
-
if (!sync_push_cloud_response.state) throw new Error(`syncPushCloud returned error: ${sync_push_cloud_response.message}`);else console.log('syncPushCloud upload response:', sync_push_cloud_response.message);
|
|
100
|
-
return true; // Return true on successful upload
|
|
101
|
-
} catch (parseError) {
|
|
102
|
-
console.error('syncPushCloud : JSON parse error:', parseError);
|
|
103
|
-
throw new Error(`syncPushCloud raised error: ${parseError}`);
|
|
104
|
-
}
|
|
105
|
-
} catch (error) {
|
|
106
|
-
if (true) {
|
|
107
|
-
console.error('syncPushCloud upload error details:', error);
|
|
108
|
-
}
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
//-----------------------------------------
|
|
114
|
-
convert_blob_picture_into_cloud_file = async pictureBlob => {
|
|
115
|
-
try {
|
|
116
|
-
console.log("Received pictureBlob in uploadPicture:cloud_url_prefix -> ", pictureBlob.cloud_url_prefix);
|
|
117
|
-
if (!pictureBlob || !pictureBlob.data) {
|
|
118
|
-
//Reset picture
|
|
119
|
-
this.setPicture("");
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
if (pictureBlob.isBlobUrl && pictureBlob.data.startsWith('blob:') && pictureBlob.cloud_url_prefix) {
|
|
123
|
-
let updloadSucces = await this.uploadToDatasyncCloud(pictureBlob); // Upload the image to custom Datasync cloud
|
|
124
|
-
if (updloadSucces) {
|
|
125
|
-
//Clear the data URL to free memory since the image is now uploaded and accessible via cloud URL
|
|
126
|
-
if (pictureBlob.data && pictureBlob.data.startsWith('blob:')) {
|
|
127
|
-
URL.revokeObjectURL(pictureBlob.data);
|
|
128
|
-
}
|
|
129
|
-
this.setData(pictureBlob.cloud_url_prefix);
|
|
130
|
-
//inform parent component of the new cloud URL for the uploaded image
|
|
131
|
-
this.props.uploadPicture({
|
|
132
|
-
data: pictureBlob.cloud_url_prefix
|
|
133
|
-
});
|
|
134
|
-
} else {
|
|
135
|
-
console.error("Upload to Datasync cloud failed - no success response received");
|
|
136
|
-
throw new Error("Upload to Datasync cloud failed - no success response received");
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.DsBlob = DsBlob;
|
|
46
|
+
const react_1 = __importStar(require("react"));
|
|
47
|
+
const datasync_core_1 = require("datasync-core");
|
|
48
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
49
|
+
function DsBlob(props) {
|
|
50
|
+
const { item_id, data: dataProp = "", binaryData: binaryDataProp = null, uploadPicture, width, height, maxWidth, maxHeight, maxKBytes, reduceImage, jpegQuality, cloud_storage, cloud_url_prefix, Caption, buttonStyle, pictureStyle, readOnly, onErrorHandler, debugging = false, } = props;
|
|
51
|
+
const [hoverInput, setHoverInput] = (0, react_1.useState)(false);
|
|
52
|
+
const [hoverImage, setHoverImage] = (0, react_1.useState)(false);
|
|
53
|
+
const [data, setDataState] = (0, react_1.useState)(dataProp || "");
|
|
54
|
+
const [, setBinaryDataState] = (0, react_1.useState)(binaryDataProp || null);
|
|
55
|
+
/** Mirrors current data state for use inside cleanup callbacks (avoids stale closures) */
|
|
56
|
+
const dataRef = (0, react_1.useRef)(data);
|
|
57
|
+
/** Off-screen <img> element used for image dimension reading and canvas drawing */
|
|
58
|
+
const _DOM_image = (0, react_1.useRef)(null);
|
|
59
|
+
//-----------------------------------------
|
|
60
|
+
/** Central setter — keeps dataRef in sync with state */
|
|
61
|
+
const setData = (newData, newBinaryData = null) => {
|
|
62
|
+
const val = newData || "";
|
|
63
|
+
dataRef.current = val;
|
|
64
|
+
setDataState(val);
|
|
65
|
+
setBinaryDataState(newBinaryData);
|
|
66
|
+
};
|
|
67
|
+
//-----------------------------------------
|
|
68
|
+
/** Route validation errors to onErrorHandler prop, or fall back to alert */
|
|
69
|
+
const reportError = (msg) => {
|
|
70
|
+
if (onErrorHandler) {
|
|
71
|
+
onErrorHandler({ error_code: "BLOB_ERROR", error_definition: msg, message: msg });
|
|
137
72
|
}
|
|
138
|
-
|
|
139
|
-
} catch (error) {
|
|
140
|
-
console.error("Upload error:", error);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
145
|
-
reduceBase64Image = e => {
|
|
146
|
-
let imageSource = e.path && e.path[0] || e.srcElement; //Safari compliancy
|
|
147
|
-
|
|
148
|
-
var canvas = document.createElement('canvas'),
|
|
149
|
-
context,
|
|
150
|
-
width = imageSource.width,
|
|
151
|
-
height = imageSource.height;
|
|
152
|
-
if (this.debugging) {
|
|
153
|
-
alert(`Debugging : pixel is ${width} x ${height}`);
|
|
154
|
-
console.log("imageSource = ", imageSource);
|
|
155
|
-
}
|
|
156
|
-
//Exact size props are set
|
|
157
|
-
if (this.props.width && this.props.height) {
|
|
158
|
-
//Check image size
|
|
159
|
-
if (width > this.props.width || height > this.props.height) {
|
|
160
|
-
let msg = `L'image est trop grande, le format requis est ${this.props.width} x ${this.props.height}`;
|
|
161
|
-
alert(msg);
|
|
162
|
-
console.error(msg);
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
//Check image size
|
|
167
|
-
if (width < this.props.width || height < this.props.height) {
|
|
168
|
-
let msg = `L'image est trop petite, le format requis est ${this.props.width} x ${this.props.height}`;
|
|
169
|
-
alert(msg);
|
|
170
|
-
console.error(msg);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
//Max size props are set
|
|
176
|
-
if (this.props.maxWidth && this.props.maxHeight) {
|
|
177
|
-
if (width > height) {
|
|
178
|
-
//This is a landscape picture orientation
|
|
179
|
-
//Check width overflow
|
|
180
|
-
if (width > this.props.maxWidth) {
|
|
181
|
-
//Check wether resize is enabled
|
|
182
|
-
if (this.props.reduceImage) {
|
|
183
|
-
//resize picture
|
|
184
|
-
height *= this.props.maxWidth / width;
|
|
185
|
-
width = this.props.maxWidth;
|
|
186
|
-
} else {
|
|
187
|
-
let msg = `L'image est trop large ! la largeur maximale est de ${this.props.maxWidth} pixels !`;
|
|
73
|
+
else {
|
|
188
74
|
alert(msg);
|
|
189
|
-
console.error(msg);
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
75
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
76
|
+
};
|
|
77
|
+
//-----------------------------------------
|
|
78
|
+
// Sync state when parent-controlled props change
|
|
79
|
+
(0, react_1.useEffect)(() => {
|
|
80
|
+
dataRef.current = dataProp || "";
|
|
81
|
+
setDataState(dataProp || "");
|
|
82
|
+
}, [dataProp]);
|
|
83
|
+
(0, react_1.useEffect)(() => {
|
|
84
|
+
setBinaryDataState(binaryDataProp || null);
|
|
85
|
+
}, [binaryDataProp]);
|
|
86
|
+
//-----------------------------------------
|
|
87
|
+
// Cleanup on unmount
|
|
88
|
+
(0, react_1.useEffect)(() => {
|
|
89
|
+
return () => {
|
|
90
|
+
cleanupBlobUrl();
|
|
91
|
+
if (_DOM_image.current) {
|
|
92
|
+
_DOM_image.current.onload = null;
|
|
93
|
+
_DOM_image.current = null;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}, []);
|
|
97
|
+
//-----------------------------------------
|
|
98
|
+
const cleanupBlobUrl = () => {
|
|
99
|
+
if (debugging) {
|
|
100
|
+
console.log(`cleanupBlobUrl ! => dataRef ${dataRef}`);
|
|
101
|
+
console.log("URL.revokeObjectURL -> dataRef.current", dataRef.current);
|
|
102
|
+
console.log("URL.revokeObjectURL -> dataRef", dataRef);
|
|
208
103
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
104
|
+
URL.revokeObjectURL(dataRef.current);
|
|
105
|
+
//Delete Blob file
|
|
106
|
+
deleteFromDatasyncCloud({
|
|
107
|
+
data: null,
|
|
108
|
+
binaryData: null,
|
|
109
|
+
cloud_url_prefix: cloud_url_prefix || "",
|
|
110
|
+
isBlobUrl: true,
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
//-----------------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Upload binary data to Datasync Cloud server using the SyncPushCloud endpoint.
|
|
116
|
+
* Returns true on success, throws on failure.
|
|
117
|
+
*/
|
|
118
|
+
const uploadToDatasyncCloud = (pictureBlob) => __awaiter(this, void 0, void 0, function* () {
|
|
119
|
+
try {
|
|
120
|
+
const formData = new FormData();
|
|
121
|
+
const cloud_filename = pictureBlob.cloud_url_prefix.split('/').pop() || "";
|
|
122
|
+
console.log("Uploading to Datasync Cloud with filename:", cloud_filename);
|
|
123
|
+
formData.append('action', "syncPushCloud");
|
|
124
|
+
formData.append('filename', cloud_filename);
|
|
125
|
+
let binaryString;
|
|
126
|
+
if (pictureBlob.isBlobUrl && pictureBlob.data.startsWith('blob:')) {
|
|
127
|
+
console.log('Fetching blob URL:', pictureBlob.data);
|
|
128
|
+
const blobResponse = yield fetch(pictureBlob.data);
|
|
129
|
+
const blob = yield blobResponse.blob();
|
|
130
|
+
const arrayBuffer = yield blob.arrayBuffer();
|
|
131
|
+
const uint8Array = new Uint8Array(arrayBuffer);
|
|
132
|
+
let binaryStr = '';
|
|
133
|
+
const chunkSize = 8192;
|
|
134
|
+
for (let i = 0; i < uint8Array.length; i += chunkSize) {
|
|
135
|
+
const chunk = uint8Array.slice(i, i + chunkSize);
|
|
136
|
+
binaryStr += String.fromCharCode(...chunk);
|
|
137
|
+
}
|
|
138
|
+
binaryString = btoa(binaryStr);
|
|
139
|
+
console.log('Converted blob URL to binary data, size:', uint8Array.length);
|
|
140
|
+
}
|
|
141
|
+
else if (Array.isArray(pictureBlob.binaryData)) {
|
|
142
|
+
const uint8Array = new Uint8Array(pictureBlob.binaryData);
|
|
143
|
+
let binaryStr = '';
|
|
144
|
+
const chunkSize = 8192;
|
|
145
|
+
for (let i = 0; i < uint8Array.length; i += chunkSize) {
|
|
146
|
+
const chunk = uint8Array.slice(i, i + chunkSize);
|
|
147
|
+
binaryStr += String.fromCharCode(...chunk);
|
|
148
|
+
}
|
|
149
|
+
binaryString = btoa(binaryStr);
|
|
150
|
+
}
|
|
151
|
+
else if (pictureBlob.binaryData instanceof Uint8Array) {
|
|
152
|
+
let binaryStr = '';
|
|
153
|
+
const chunkSize = 8192;
|
|
154
|
+
for (let i = 0; i < pictureBlob.binaryData.length; i += chunkSize) {
|
|
155
|
+
const chunk = pictureBlob.binaryData.slice(i, i + chunkSize);
|
|
156
|
+
binaryStr += String.fromCharCode(...chunk);
|
|
157
|
+
}
|
|
158
|
+
binaryString = btoa(binaryStr);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
binaryString = pictureBlob.binaryData || "";
|
|
162
|
+
}
|
|
163
|
+
formData.append('binary', binaryString);
|
|
164
|
+
if (debugging)
|
|
165
|
+
console.log("binaryString ->", binaryString.substring(0, 100) + '...');
|
|
166
|
+
const results = yield fetch('http://localhost:8888/datasync-service/Sync.php', {
|
|
167
|
+
method: 'POST',
|
|
168
|
+
body: formData,
|
|
244
169
|
});
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
170
|
+
if (!results.ok) {
|
|
171
|
+
throw new Error(`HTTP error! status: ${results.statusText}`);
|
|
172
|
+
}
|
|
173
|
+
const sync_push_cloud_response = yield results.json();
|
|
174
|
+
if (!sync_push_cloud_response.state)
|
|
175
|
+
throw new Error(`syncPushCloud returned error: ${sync_push_cloud_response.message}`);
|
|
176
|
+
console.log('syncPushCloud upload response:', sync_push_cloud_response.message);
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
console.error('syncPushCloud upload error details:', error);
|
|
181
|
+
throw error;
|
|
249
182
|
}
|
|
250
|
-
}, 'image/jpeg', jpegCompressionRatio);
|
|
251
|
-
} else {
|
|
252
|
-
//Jpeg conversion
|
|
253
|
-
|
|
254
|
-
let canvasData = canvas.toDataURL('image/jpg', jpegCompressionRatio); //Jpeg conversion
|
|
255
|
-
|
|
256
|
-
if (this.debugging) console.log("jpegCompressionRatio->", jpegCompressionRatio, " canvasData.length = ", canvasData.length);
|
|
257
|
-
const processedData = canvasData ? canvasData : "";
|
|
258
|
-
this.setData(processedData);
|
|
259
|
-
|
|
260
|
-
//Keep base 64 prefix as it is
|
|
261
|
-
this.props.uploadPicture({
|
|
262
|
-
data: processedData
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
268
|
-
storeBase64ImageToImg = e => {
|
|
269
|
-
var DOM_image = document.createElement('img');
|
|
270
|
-
DOM_image.onload = this.reduceBase64Image;
|
|
271
|
-
console.log("storeBase64ImageToImg:e.currentTarget.result = ", e.currentTarget.result);
|
|
272
|
-
DOM_image.src = e.currentTarget.result;
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
276
|
-
readImageAsBase64 = async aPictureFile => {
|
|
277
|
-
let _reader = new FileReader();
|
|
278
|
-
console.log("readImageAsBase64:aPictureFile = ", aPictureFile);
|
|
279
|
-
_reader.onload = this.storeBase64ImageToImg;
|
|
280
|
-
_reader.readAsDataURL(aPictureFile); //The readAsDataURL() method of the FileReader interface is used to read the contents of the specified file's data as a base64 encoded string.
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
284
|
-
resetUpload = () => {
|
|
285
|
-
// Clean up any blob URLs before resetting
|
|
286
|
-
this.cleanupBlobUrl();
|
|
287
|
-
this.setData("", null);
|
|
288
|
-
this.props.uploadPicture({
|
|
289
|
-
data: "",
|
|
290
|
-
cloud_url_prefix: this.props.cloud_url_prefix,
|
|
291
|
-
isBlobUrl: false
|
|
292
183
|
});
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
325
|
-
componentWillUnmount() {
|
|
326
|
-
// Cleanup blob URLs when component unmounts
|
|
327
|
-
this.cleanupBlobUrl();
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
331
|
-
onInputChange = e => {
|
|
332
|
-
const errs = [];
|
|
333
|
-
const files = Array.from(e.target.files);
|
|
334
|
-
const types = ['image/png', 'image/jpeg', 'image/gif'];
|
|
335
|
-
const _1Mo = 1024 * 1024;
|
|
336
|
-
const SizeLimit = 9;
|
|
337
|
-
|
|
338
|
-
//Reset input cache value - to assure trigger if user select the same file again
|
|
339
|
-
e.target.value = null;
|
|
340
|
-
if (this.debugging) console.log("onInputChange");
|
|
341
|
-
if (files.length > 1) {
|
|
342
|
-
const msg = 'Pas plus d\'une image à la fois';
|
|
343
|
-
alert(msg);
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
files.forEach((file, i) => {
|
|
347
|
-
let errCount = errs.length;
|
|
348
|
-
if (types.every(type => file.type !== type)) {
|
|
349
|
-
errs.push(`'${file.type}' : format non supporté`);
|
|
350
|
-
}
|
|
351
|
-
if (file.size > SizeLimit * _1Mo) {
|
|
352
|
-
errs.push(`'${file.name}' image trop volumineuse (max:${SizeLimit}Méga-octets)`);
|
|
353
|
-
}
|
|
354
|
-
if (this.debugging) console.log(`errCount = ${errCount} vs errs.length = ${errs.length}`);
|
|
355
|
-
if (errCount == errs.length) {
|
|
356
|
-
//None new error occurs
|
|
357
|
-
if (this.debugging) console.log("readImageAsBase64::", file.name);
|
|
358
|
-
this.readImageAsBase64(file);
|
|
359
|
-
}
|
|
184
|
+
//-----------------------------------------
|
|
185
|
+
const convert_blob_picture_into_cloud_file = (pictureBlob) => __awaiter(this, void 0, void 0, function* () {
|
|
186
|
+
try {
|
|
187
|
+
console.log("Received pictureBlob in uploadPicture:cloud_url_prefix -> ", pictureBlob.cloud_url_prefix);
|
|
188
|
+
if (!pictureBlob || !pictureBlob.data) {
|
|
189
|
+
setData("");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (pictureBlob.isBlobUrl && pictureBlob.data.startsWith('blob:') && pictureBlob.cloud_url_prefix) {
|
|
193
|
+
const uploadSuccess = yield uploadToDatasyncCloud(pictureBlob);
|
|
194
|
+
if (uploadSuccess) {
|
|
195
|
+
if (pictureBlob.data && pictureBlob.data.startsWith('blob:')) {
|
|
196
|
+
URL.revokeObjectURL(pictureBlob.data);
|
|
197
|
+
}
|
|
198
|
+
console.log("convert_blob_picture_into_cloud_file::New picture loaded then Refresh :-o");
|
|
199
|
+
setData(pictureBlob.cloud_url_prefix);
|
|
200
|
+
uploadPicture({ data: pictureBlob.cloud_url_prefix });
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
const msg = "Upload to Datasync cloud failed - no success response received";
|
|
204
|
+
console.error(msg);
|
|
205
|
+
throw new Error(msg);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
console.error("Upload error:", error);
|
|
211
|
+
}
|
|
360
212
|
});
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
392
|
-
// Data getter and setter methods for read-write access
|
|
393
|
-
getData = () => {
|
|
394
|
-
return this.state.data;
|
|
395
|
-
};
|
|
396
|
-
setData = (data, binaryData = null) => {
|
|
397
|
-
this.setState({
|
|
398
|
-
data: data || "",
|
|
399
|
-
binaryData: binaryData
|
|
213
|
+
//-----------------------------------------
|
|
214
|
+
/**
|
|
215
|
+
* Delete binary data file from Datasync Cloud server using the SyncDeleteCloud endpoint.
|
|
216
|
+
* Returns true on success, throws on failure.
|
|
217
|
+
*/
|
|
218
|
+
const deleteFromDatasyncCloud = (pictureBlob) => __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
try {
|
|
220
|
+
const formData = new FormData();
|
|
221
|
+
const cloud_filename = pictureBlob.cloud_url_prefix.split('/').pop() || "";
|
|
222
|
+
console.log("Deleting from Datasync Cloud with filename:", cloud_filename);
|
|
223
|
+
formData.append('action', "syncDeleteCloud");
|
|
224
|
+
formData.append('filename', cloud_filename);
|
|
225
|
+
const results = yield fetch('http://localhost:8888/datasync-service/Sync.php', {
|
|
226
|
+
method: 'POST',
|
|
227
|
+
body: formData,
|
|
228
|
+
});
|
|
229
|
+
if (!results.ok) {
|
|
230
|
+
throw new Error(`HTTP error! status: ${results.statusText}`);
|
|
231
|
+
}
|
|
232
|
+
const sync_delete_cloud_response = yield results.json();
|
|
233
|
+
if (!sync_delete_cloud_response.state)
|
|
234
|
+
throw new Error(`syncDeleteCloud returned error: ${sync_delete_cloud_response.message}`);
|
|
235
|
+
console.log('syncDeleteCloud upload response:', sync_delete_cloud_response.message);
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
console.error('syncDeleteCloud upload error details:', error);
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
400
242
|
});
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
243
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
244
|
+
const reduceBase64Image = (e) => {
|
|
245
|
+
const imageSource = e.target;
|
|
246
|
+
const canvas = document.createElement('canvas');
|
|
247
|
+
let w = imageSource.width;
|
|
248
|
+
let h = imageSource.height;
|
|
249
|
+
if (debugging) {
|
|
250
|
+
console.log(`Debugging : pixel is ${w} x ${h} imageSource => ${imageSource}`);
|
|
251
|
+
}
|
|
252
|
+
// Exact size constraints
|
|
253
|
+
if (width && height) {
|
|
254
|
+
if (w > width || h > height) {
|
|
255
|
+
const msg = `L'image est trop grande, le format requis est ${width} x ${height}`;
|
|
256
|
+
reportError(msg);
|
|
257
|
+
console.error(msg);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (w < width || h < height) {
|
|
261
|
+
const msg = `L'image est trop petite, le format requis est ${width} x ${height}`;
|
|
262
|
+
reportError(msg);
|
|
263
|
+
console.error(msg);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Maximum size constraints
|
|
268
|
+
if (maxWidth && maxHeight) {
|
|
269
|
+
if (w > h) {
|
|
270
|
+
// Landscape orientation
|
|
271
|
+
if (w > maxWidth) {
|
|
272
|
+
if (reduceImage) {
|
|
273
|
+
h *= maxWidth / w;
|
|
274
|
+
w = maxWidth;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
const msg = `L'image est trop large ! la largeur maximale est de ${maxWidth} pixels !`;
|
|
278
|
+
reportError(msg);
|
|
279
|
+
console.error(msg);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
// Portrait orientation
|
|
286
|
+
if (h > maxHeight) {
|
|
287
|
+
if (reduceImage) {
|
|
288
|
+
w *= maxHeight / h;
|
|
289
|
+
h = maxHeight;
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
const msg = `L'image est trop haute, la hauteur maximale est de ${maxHeight} pixels`;
|
|
293
|
+
reportError(msg);
|
|
294
|
+
console.error(msg);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const jpegCompressionRatio = (jpegQuality && jpegQuality > 0 && jpegQuality < 1) ? jpegQuality : 1;
|
|
301
|
+
canvas.width = w;
|
|
302
|
+
canvas.height = h;
|
|
303
|
+
const context = canvas.getContext('2d');
|
|
304
|
+
context.drawImage(imageSource, 0, 0, w, h);
|
|
305
|
+
if (cloud_storage) {
|
|
306
|
+
canvas.toBlob((blob) => __awaiter(this, void 0, void 0, function* () {
|
|
307
|
+
if (blob) {
|
|
308
|
+
if (debugging) {
|
|
309
|
+
console.log("Binary blob created, size:", blob.size);
|
|
310
|
+
console.log("jpegCompressionRatio->", jpegCompressionRatio, " blob.size = ", blob.size);
|
|
311
|
+
}
|
|
312
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
313
|
+
const reader = new FileReader();
|
|
314
|
+
reader.onload = () => {
|
|
315
|
+
const binaryData = reader.result;
|
|
316
|
+
console.log("Fallback: Using binary data, size:", binaryData.byteLength);
|
|
317
|
+
convert_blob_picture_into_cloud_file({
|
|
318
|
+
data: blobUrl,
|
|
319
|
+
binaryData: binaryData,
|
|
320
|
+
cloud_url_prefix: cloud_url_prefix || "",
|
|
321
|
+
isBlobUrl: true,
|
|
322
|
+
});
|
|
323
|
+
//--let us revoque image If the image comes from URL.createObjectURL(...), call URL.revokeObjectURL(...) after replacing it.
|
|
324
|
+
if (debugging)
|
|
325
|
+
console.log("URL.revokeObjectURL --> blobUrl", blobUrl);
|
|
326
|
+
URL.revokeObjectURL(blobUrl);
|
|
327
|
+
};
|
|
328
|
+
reader.readAsArrayBuffer(blob);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
console.error("Failed to create blob from canvas");
|
|
332
|
+
}
|
|
333
|
+
}), 'image/jpeg', jpegCompressionRatio);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
const canvasData = canvas.toDataURL('image/jpg', jpegCompressionRatio);
|
|
337
|
+
if (debugging)
|
|
338
|
+
console.log("jpegCompressionRatio->", jpegCompressionRatio, " canvasData.length = ", canvasData.length);
|
|
339
|
+
const processedData = canvasData || "";
|
|
340
|
+
setData(processedData);
|
|
341
|
+
uploadPicture({ data: processedData });
|
|
342
|
+
}
|
|
414
343
|
};
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
344
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
345
|
+
const storeBase64ImageToImg = (e) => {
|
|
346
|
+
var _a;
|
|
347
|
+
const domImage = document.createElement('img');
|
|
348
|
+
domImage.setAttribute("id", `img_tmp_id_${(0, datasync_core_1.CGUID)()}`);
|
|
349
|
+
_DOM_image.current = domImage;
|
|
350
|
+
domImage.onload = reduceBase64Image;
|
|
351
|
+
const result = (_a = e.currentTarget) === null || _a === void 0 ? void 0 : _a.result;
|
|
352
|
+
console.log("storeBase64ImageToImg:e.currentTarget.result = ", result);
|
|
353
|
+
domImage.src = result;
|
|
419
354
|
};
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
355
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
356
|
+
const readImageAsBase64 = (aPictureFile) => {
|
|
357
|
+
const _reader = new FileReader();
|
|
358
|
+
console.log("readImageAsBase64:aPictureFile = ", aPictureFile);
|
|
359
|
+
_reader.onload = storeBase64ImageToImg;
|
|
360
|
+
_reader.readAsDataURL(aPictureFile);
|
|
424
361
|
};
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
362
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
363
|
+
const resetUpload = () => {
|
|
364
|
+
cleanupBlobUrl();
|
|
365
|
+
setData("", null);
|
|
366
|
+
uploadPicture({ data: "", cloud_url_prefix: "", isBlobUrl: false });
|
|
428
367
|
};
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
368
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
369
|
+
const onInputChange = (e) => {
|
|
370
|
+
const errs = [];
|
|
371
|
+
const files = Array.from(e.target.files || []);
|
|
372
|
+
const types = ['image/png', 'image/jpeg', 'image/gif'];
|
|
373
|
+
const _1Mo = 1024 * 1024;
|
|
374
|
+
const sizeLimitBytes = maxKBytes ? maxKBytes * 1024 : 9 * _1Mo;
|
|
375
|
+
// Reset input value — ensures the same file can be selected again
|
|
376
|
+
e.target.value = "";
|
|
377
|
+
if (debugging)
|
|
378
|
+
console.log("onInputChange");
|
|
379
|
+
if (files.length > 1) {
|
|
380
|
+
reportError("Pas plus d'une image à la fois");
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
files.forEach((file) => {
|
|
384
|
+
const errCount = errs.length;
|
|
385
|
+
if (types.every((type) => file.type !== type)) {
|
|
386
|
+
errs.push(`'${file.type}' : format non supporté`);
|
|
387
|
+
}
|
|
388
|
+
if (file.size > sizeLimitBytes) {
|
|
389
|
+
const limitLabel = maxKBytes ? `${maxKBytes}Ko` : `9Méga-octets`;
|
|
390
|
+
errs.push(`'${file.name}' image trop volumineuse (max:${limitLabel})`);
|
|
391
|
+
}
|
|
392
|
+
if (debugging)
|
|
393
|
+
console.log(`errCount = ${errCount} vs errs.length = ${errs.length}`);
|
|
394
|
+
if (errCount === errs.length) {
|
|
395
|
+
if (debugging)
|
|
396
|
+
console.log("readImageAsBase64::", file.name);
|
|
397
|
+
readImageAsBase64(file);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
if (errs.length) {
|
|
401
|
+
errs.forEach((err) => reportError(err));
|
|
402
|
+
}
|
|
434
403
|
};
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
404
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
405
|
+
const getImageSrc = () => {
|
|
406
|
+
if (!data)
|
|
407
|
+
return "";
|
|
408
|
+
if (data.startsWith('http://') || data.startsWith('https://') || data.startsWith('blob:')) {
|
|
409
|
+
return data;
|
|
410
|
+
}
|
|
411
|
+
if (data.startsWith('data:')) {
|
|
412
|
+
return data;
|
|
413
|
+
}
|
|
414
|
+
return data;
|
|
439
415
|
};
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
hover_input: false,
|
|
465
|
-
hover_image: false
|
|
466
|
-
}, () => {
|
|
467
|
-
if (this.debugging) console.log("onMouseLeave");
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
}, /*#__PURE__*/_react.default.createElement("img", {
|
|
471
|
-
style: this.state.hover_image ? div_show_image_hover : div_show_image,
|
|
472
|
-
src: this.getImageSrc(),
|
|
473
|
-
className: this.props.pictureStyle
|
|
474
|
-
}), !this.props.readOnly && /*#__PURE__*/_react.default.createElement("input", {
|
|
475
|
-
style: this.state.hover_input ? div_show_image_hover_input : div_show_image_input,
|
|
476
|
-
className: "btn btn-primary delete",
|
|
477
|
-
type: "button",
|
|
478
|
-
value: "Effacer",
|
|
479
|
-
onClick: this.resetUpload
|
|
480
|
-
})));
|
|
481
|
-
}
|
|
416
|
+
//-----------------------------------------------------------------------------------------------------------------------------------------
|
|
417
|
+
const upload_picture_label = { cursor: "pointer" };
|
|
418
|
+
const upload_picture_label_input = { opacity: 0, width: "0px", height: "0px" };
|
|
419
|
+
const div_show_image_hover = { position: "relative", margin: "0px", opacity: 0.5 };
|
|
420
|
+
const div_show_image = { position: "relative", margin: "0px" };
|
|
421
|
+
const div_show_image_hover_input = { display: "block", top: "0px", left: "0px", position: "absolute" };
|
|
422
|
+
const div_show_image_input = { position: "absolute", display: "none", cursor: "pointer" };
|
|
423
|
+
return (react_1.default.createElement("div", null,
|
|
424
|
+
!data &&
|
|
425
|
+
react_1.default.createElement("label", { id: "upload-picture-label", className: buttonStyle, style: upload_picture_label },
|
|
426
|
+
Caption,
|
|
427
|
+
react_1.default.createElement("input", { style: upload_picture_label_input, id: "nested-input", type: "file", accept: "image/*", onChange: onInputChange, multiple: true })),
|
|
428
|
+
data && data.length > 0 &&
|
|
429
|
+
react_1.default.createElement("div", { className: "show-image", style: div_show_image, onMouseOver: () => { setHoverInput(true); setHoverImage(true); if (debugging)
|
|
430
|
+
console.log("onMouseOver"); }, onMouseLeave: () => { setHoverInput(false); setHoverImage(false); if (debugging)
|
|
431
|
+
console.log("onMouseLeave"); } },
|
|
432
|
+
react_1.default.createElement("img", { style: hoverImage ? div_show_image_hover : div_show_image, src: getImageSrc(), className: pictureStyle, alt: "", id: `img_id_${(0, datasync_core_1.CGUID)()}` }),
|
|
433
|
+
!readOnly &&
|
|
434
|
+
react_1.default.createElement("input", { style: hoverInput ? div_show_image_hover_input : div_show_image_input, className: "btn btn-primary delete", type: "button", value: "Effacer", onClick: resetUpload }),
|
|
435
|
+
!readOnly &&
|
|
436
|
+
react_1.default.createElement("label", { style: hoverInput
|
|
437
|
+
? Object.assign(Object.assign({}, div_show_image_hover_input), { top: "32px", cursor: "pointer" }) : div_show_image_input, className: "btn btn-secondary" },
|
|
438
|
+
Caption || 'Remplacer',
|
|
439
|
+
react_1.default.createElement("input", { style: upload_picture_label_input, type: "file", accept: "image/*", onChange: onInputChange, multiple: true })))));
|
|
482
440
|
}
|
|
483
|
-
exports.DsBlob = DsBlob;
|
|
484
|
-
DsBlob.propTypes = {
|
|
485
|
-
// Image handling props (note: data and binaryData are managed as read-write state internally)
|
|
486
|
-
data: _propTypes.default.string,
|
|
487
|
-
binaryData: _propTypes.default.object,
|
|
488
|
-
// Upload callback
|
|
489
|
-
uploadPicture: _propTypes.default.func.isRequired,
|
|
490
|
-
// Image size constraints
|
|
491
|
-
width: _propTypes.default.number,
|
|
492
|
-
height: _propTypes.default.number,
|
|
493
|
-
maxWidth: _propTypes.default.number,
|
|
494
|
-
maxHeight: _propTypes.default.number,
|
|
495
|
-
// Image processing options
|
|
496
|
-
reduceImage: _propTypes.default.bool,
|
|
497
|
-
jpegQuality: _propTypes.default.number,
|
|
498
|
-
// Cloud storage options
|
|
499
|
-
cloud_storage: _propTypes.default.bool,
|
|
500
|
-
cloud_url_prefix: _propTypes.default.string,
|
|
501
|
-
// UI props
|
|
502
|
-
Caption: _propTypes.default.string,
|
|
503
|
-
buttonStyle: _propTypes.default.string,
|
|
504
|
-
pictureStyle: _propTypes.default.string,
|
|
505
|
-
readOnly: _propTypes.default.bool,
|
|
506
|
-
// Status flags
|
|
507
|
-
isCloudUrl: _propTypes.default.bool,
|
|
508
|
-
isBlobUrl: _propTypes.default.bool
|
|
509
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "datasync-blob",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.34",
|
|
4
4
|
"description": "Datasync Blob component",
|
|
5
5
|
"main": "./dist/components/DsBlob.js",
|
|
6
6
|
"files": [
|
|
@@ -15,32 +15,27 @@
|
|
|
15
15
|
"email": "pmabiala@me.com"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@babel/
|
|
19
|
-
"@
|
|
20
|
-
"@
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"jest-transform-css": "^6.0.1",
|
|
27
|
-
"react": "^18.2.0",
|
|
28
|
-
"react-pdf": "^7.7.1",
|
|
29
|
-
"webpack": "^5.99.9",
|
|
30
|
-
"webpack-cli": "^6.0.1",
|
|
31
|
-
"webpack-node-externals": "^3.0.0",
|
|
32
|
-
"webpack-obfuscator": "^3.5.1"
|
|
18
|
+
"@babel/preset-typescript": "^7.29.7",
|
|
19
|
+
"@types/react": "^18.3.29",
|
|
20
|
+
"@types/react-dom": "^18.3.7",
|
|
21
|
+
"datasync-core": "^1.0.46",
|
|
22
|
+
"multiselect-react-dropdown": "^2.0.25",
|
|
23
|
+
"react": ">=18.2.0",
|
|
24
|
+
"reactstrap": ">=8.4.1",
|
|
25
|
+
"typescript": "^5.9.3"
|
|
33
26
|
},
|
|
34
27
|
"peerDependencies": {
|
|
35
28
|
"react": "^ 18.2.0"
|
|
36
29
|
},
|
|
37
30
|
"scripts": {
|
|
38
|
-
"
|
|
39
|
-
"build": "rm -r dist && babel src -d dist --ignore src/**/*.test.jsx && npm run copy-files && webpack --config webpack.config.js",
|
|
40
|
-
"copy-files": "cp ./src/*.css dist/",
|
|
41
|
-
"test": "jest --config jest.config.json"
|
|
31
|
+
"hybrid": "tsc && cp src/flex-grid.css dist/flex-grid.css"
|
|
42
32
|
},
|
|
43
33
|
"keywords": [],
|
|
44
34
|
"author": "",
|
|
45
|
-
"license": "ISC"
|
|
35
|
+
"license": "ISC",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"axios": "^1.7.2",
|
|
38
|
+
"datasync-blob": "^1.1.32",
|
|
39
|
+
"runscripts": "^0.0.1"
|
|
40
|
+
}
|
|
46
41
|
}
|