@bpmn-io/form-js-viewer 1.14.0 → 1.15.0
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/index.cjs +101 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +101 -71
- package/dist/index.es.js.map +1 -1
- package/dist/types/render/components/form-fields/DocumentPreview.d.ts +9 -7
- package/dist/types/render/components/index.d.ts +1 -1
- package/dist/types/util/constants/DatetimeConstants.d.ts +6 -2
- package/dist/types/util/constants/OptionsSourceConstants.d.ts +9 -3
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -927,7 +927,6 @@ function useDeepCompareMemoize(value) {
|
|
|
927
927
|
* @enum { String }
|
|
928
928
|
*/
|
|
929
929
|
const LOAD_STATES = {
|
|
930
|
-
LOADING: 'loading',
|
|
931
930
|
LOADED: 'loaded',
|
|
932
931
|
ERROR: 'error'
|
|
933
932
|
};
|
|
@@ -1138,6 +1137,9 @@ function _isElementScrollable(el) {
|
|
|
1138
1137
|
return (overflowY === 'auto' || overflowY === 'scroll') && el.scrollHeight > el.clientHeight;
|
|
1139
1138
|
}
|
|
1140
1139
|
|
|
1140
|
+
const EMPTY_OBJECT = {};
|
|
1141
|
+
const EMPTY_ARRAY$2 = [];
|
|
1142
|
+
|
|
1141
1143
|
/**
|
|
1142
1144
|
* Custom hook to scroll an element within a scrollable container.
|
|
1143
1145
|
*
|
|
@@ -1151,8 +1153,8 @@ function _isElementScrollable(el) {
|
|
|
1151
1153
|
* @param {Array} [flagRefs] - An array of refs that are used as flags to control when to scroll.
|
|
1152
1154
|
*/
|
|
1153
1155
|
function useScrollIntoView(scrolledElementRef, deps, scrollOptions, flagRefs) {
|
|
1154
|
-
const _scrollOptions = scrollOptions;
|
|
1155
|
-
const _flagRefs = flagRefs;
|
|
1156
|
+
const _scrollOptions = scrollOptions || EMPTY_OBJECT;
|
|
1157
|
+
const _flagRefs = flagRefs || EMPTY_ARRAY$2;
|
|
1156
1158
|
hooks.useEffect(() => {
|
|
1157
1159
|
// return early if flags are not raised, or component is not mounted
|
|
1158
1160
|
if (minDash.some(_flagRefs, ref => !ref.current) || !scrolledElementRef.current) {
|
|
@@ -5921,10 +5923,15 @@ var SvgDownload = function SvgDownload(props) {
|
|
|
5921
5923
|
|
|
5922
5924
|
const type = 'documentPreview';
|
|
5923
5925
|
|
|
5926
|
+
/**
|
|
5927
|
+
* @typedef DocumentEndpointBuilder
|
|
5928
|
+
* @property {(document: DocumentMetadata) => string} buildUrl
|
|
5929
|
+
*/
|
|
5930
|
+
|
|
5924
5931
|
/**
|
|
5925
5932
|
* @typedef DocumentMetadata
|
|
5926
5933
|
* @property {string} documentId
|
|
5927
|
-
* @property {string}
|
|
5934
|
+
* @property {string} endpoint
|
|
5928
5935
|
* @property {Object} metadata
|
|
5929
5936
|
* @property {string|undefined} [metadata.contentType]
|
|
5930
5937
|
* @property {string} metadata.fileName
|
|
@@ -5933,7 +5940,6 @@ const type = 'documentPreview';
|
|
|
5933
5940
|
* @property {string} id
|
|
5934
5941
|
* @property {string} [title]
|
|
5935
5942
|
* @property {string} [dataSource]
|
|
5936
|
-
* @property {string} [endpointKey]
|
|
5937
5943
|
* @property {number} [maxHeight]
|
|
5938
5944
|
* @property {string} [label]
|
|
5939
5945
|
*
|
|
@@ -5945,18 +5951,18 @@ const type = 'documentPreview';
|
|
|
5945
5951
|
* @returns {import("preact").JSX.Element}
|
|
5946
5952
|
*/
|
|
5947
5953
|
function DocumentPreview(props) {
|
|
5954
|
+
/** @type {DocumentEndpointBuilder | null} */
|
|
5955
|
+
const documentEndpointBuilder = useService('documentEndpointBuilder', false);
|
|
5948
5956
|
const {
|
|
5949
5957
|
field,
|
|
5950
5958
|
domId
|
|
5951
5959
|
} = props;
|
|
5952
5960
|
const {
|
|
5953
5961
|
dataSource,
|
|
5954
|
-
endpointKey,
|
|
5955
5962
|
maxHeight,
|
|
5956
5963
|
label
|
|
5957
5964
|
} = field;
|
|
5958
5965
|
const errorMessageId = `${domId}-error-message`;
|
|
5959
|
-
const endpoint = useExpressionEvaluation(endpointKey || '');
|
|
5960
5966
|
const data = useValidDocumentData(dataSource || '');
|
|
5961
5967
|
const evaluatedLabel = useSingleLineTemplateEvaluation(label, {
|
|
5962
5968
|
debug: true
|
|
@@ -5969,18 +5975,19 @@ function DocumentPreview(props) {
|
|
|
5969
5975
|
}), jsxRuntime.jsx("div", {
|
|
5970
5976
|
class: `fjs-${type}-document-container`,
|
|
5971
5977
|
id: domId,
|
|
5972
|
-
children:
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
+
children: data.map((document, index) => {
|
|
5979
|
+
const finalEndpoint = tryCatch(() => documentEndpointBuilder?.buildUrl(document)) ?? document.endpoint;
|
|
5980
|
+
return isValidDocumentEndpoint(finalEndpoint) ? jsxRuntime.jsx(DocumentRenderer, {
|
|
5981
|
+
documentMetadata: document,
|
|
5982
|
+
endpoint: finalEndpoint,
|
|
5983
|
+
maxHeight: maxHeight,
|
|
5984
|
+
domId: `${domId}-${index}`
|
|
5985
|
+
}, document.documentId) : null;
|
|
5986
|
+
})
|
|
5978
5987
|
}), jsxRuntime.jsx(Errors, {
|
|
5979
5988
|
id: errorMessageId,
|
|
5980
5989
|
errors: getErrors({
|
|
5981
|
-
dataSource
|
|
5982
|
-
endpoint,
|
|
5983
|
-
endpointKey
|
|
5990
|
+
dataSource
|
|
5984
5991
|
})
|
|
5985
5992
|
})]
|
|
5986
5993
|
});
|
|
@@ -5992,43 +5999,27 @@ DocumentPreview.config = {
|
|
|
5992
5999
|
name: 'Document preview',
|
|
5993
6000
|
create: (options = {}) => ({
|
|
5994
6001
|
label: 'Document preview',
|
|
5995
|
-
endpointKey: DEFAULT_ENDPOINT_KEY,
|
|
5996
6002
|
...options
|
|
5997
6003
|
})
|
|
5998
6004
|
};
|
|
5999
6005
|
|
|
6000
6006
|
// helpers /////////////////////////////
|
|
6001
6007
|
|
|
6002
|
-
const DOCUMENT_ID_PLACEHOLDER = '{documentId}';
|
|
6003
|
-
const DEFAULT_ENDPOINT_KEY = '=defaultDocumentsEndpointKey';
|
|
6004
|
-
|
|
6005
6008
|
/**
|
|
6006
6009
|
* @typedef GetErrorOptions
|
|
6007
6010
|
* @property {string|undefined} dataSource
|
|
6008
|
-
* @property {string|undefined} endpointKey
|
|
6009
|
-
* @property {string|null} endpoint
|
|
6010
6011
|
*
|
|
6011
6012
|
* @param {GetErrorOptions} options
|
|
6012
6013
|
* @returns {string[]}
|
|
6013
6014
|
*/
|
|
6014
6015
|
function getErrors(options) {
|
|
6015
6016
|
const {
|
|
6016
|
-
dataSource
|
|
6017
|
-
endpointKey,
|
|
6018
|
-
endpoint
|
|
6017
|
+
dataSource
|
|
6019
6018
|
} = options;
|
|
6020
6019
|
let errors = [];
|
|
6021
6020
|
if (!minDash.isString(dataSource) || dataSource.length < 1) {
|
|
6022
6021
|
errors.push('Document reference is not defined.');
|
|
6023
6022
|
}
|
|
6024
|
-
if (!minDash.isString(endpointKey) || endpointKey.length < 1) {
|
|
6025
|
-
errors.push('Endpoint key is not defined.');
|
|
6026
|
-
}
|
|
6027
|
-
if (endpointKey !== DEFAULT_ENDPOINT_KEY && !URL.canParse(endpoint)) {
|
|
6028
|
-
errors.push(`If you change the endpoint key from "${DEFAULT_ENDPOINT_KEY}", the document preview won't work with Camunda Tasklist and you must provide a valid URL.`);
|
|
6029
|
-
} else if (endpointKey !== DEFAULT_ENDPOINT_KEY && !isValidDocumentEndpoint(endpoint)) {
|
|
6030
|
-
errors.push('Endpoint must contain "{documentId}".');
|
|
6031
|
-
}
|
|
6032
6023
|
return errors;
|
|
6033
6024
|
}
|
|
6034
6025
|
|
|
@@ -6038,7 +6029,7 @@ function getErrors(options) {
|
|
|
6038
6029
|
* @returns boolean
|
|
6039
6030
|
*/
|
|
6040
6031
|
function isValidDocumentEndpoint(endpoint) {
|
|
6041
|
-
return typeof endpoint === 'string' && URL.canParse(endpoint)
|
|
6032
|
+
return typeof endpoint === 'string' && URL.canParse(endpoint);
|
|
6042
6033
|
}
|
|
6043
6034
|
|
|
6044
6035
|
/**
|
|
@@ -6061,6 +6052,61 @@ function useValidDocumentData(dataSource) {
|
|
|
6061
6052
|
return data.filter(isValidDocument);
|
|
6062
6053
|
}
|
|
6063
6054
|
|
|
6055
|
+
/**
|
|
6056
|
+
* @param {Object} props
|
|
6057
|
+
* @param {string} props.url
|
|
6058
|
+
* @param {string} props.fileName
|
|
6059
|
+
* @param {Function} props.onError
|
|
6060
|
+
* @param {string} props.errorMessageId
|
|
6061
|
+
* @returns {import("preact").JSX.Element}
|
|
6062
|
+
*/
|
|
6063
|
+
function PdfRenderer(props) {
|
|
6064
|
+
const {
|
|
6065
|
+
url,
|
|
6066
|
+
onError,
|
|
6067
|
+
errorMessageId
|
|
6068
|
+
} = props;
|
|
6069
|
+
/** @type {ReturnType<typeof import("preact/hooks").useState<null | string>>} */
|
|
6070
|
+
const [pdfObjectUrl, setPdfObjectUrl] = hooks.useState(null);
|
|
6071
|
+
const [hasError, setHasError] = hooks.useState(false);
|
|
6072
|
+
hooks.useEffect(() => {
|
|
6073
|
+
/** @type {null | string} */
|
|
6074
|
+
let objectUrl = null;
|
|
6075
|
+
const fetchPdf = async () => {
|
|
6076
|
+
try {
|
|
6077
|
+
const response = await fetch(url);
|
|
6078
|
+
if (!response.ok) {
|
|
6079
|
+
setHasError(true);
|
|
6080
|
+
onError();
|
|
6081
|
+
return;
|
|
6082
|
+
}
|
|
6083
|
+
const blob = await response.blob();
|
|
6084
|
+
objectUrl = URL.createObjectURL(blob);
|
|
6085
|
+
setPdfObjectUrl(objectUrl);
|
|
6086
|
+
} catch {
|
|
6087
|
+
setHasError(true);
|
|
6088
|
+
onError();
|
|
6089
|
+
}
|
|
6090
|
+
};
|
|
6091
|
+
fetchPdf();
|
|
6092
|
+
return () => {
|
|
6093
|
+
if (objectUrl) {
|
|
6094
|
+
URL.revokeObjectURL(objectUrl);
|
|
6095
|
+
}
|
|
6096
|
+
};
|
|
6097
|
+
}, [url, onError]);
|
|
6098
|
+
return jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
6099
|
+
children: [pdfObjectUrl !== null ? jsxRuntime.jsx("embed", {
|
|
6100
|
+
src: pdfObjectUrl,
|
|
6101
|
+
type: "application/pdf",
|
|
6102
|
+
class: `fjs-${type}-pdf-viewer`
|
|
6103
|
+
}) : null, hasError ? jsxRuntime.jsx(Errors, {
|
|
6104
|
+
id: errorMessageId,
|
|
6105
|
+
errors: ['Unable to download document']
|
|
6106
|
+
}) : null]
|
|
6107
|
+
});
|
|
6108
|
+
}
|
|
6109
|
+
|
|
6064
6110
|
/**
|
|
6065
6111
|
*
|
|
6066
6112
|
* @param {Object} props
|
|
@@ -6084,11 +6130,6 @@ function DocumentRenderer(props) {
|
|
|
6084
6130
|
const [hasError, setHasError] = hooks.useState(false);
|
|
6085
6131
|
const ref = hooks.useRef(null);
|
|
6086
6132
|
const isInViewport = useInViewport(ref);
|
|
6087
|
-
const fullUrl = buildUrl({
|
|
6088
|
-
baseUrl: endpoint,
|
|
6089
|
-
documentId: documentMetadata.documentId,
|
|
6090
|
-
contentHash: documentMetadata.contentHash
|
|
6091
|
-
});
|
|
6092
6133
|
const singleDocumentContainerClassName = `fjs-${type}-single-document-container`;
|
|
6093
6134
|
const errorMessageId = `${domId}-error-message`;
|
|
6094
6135
|
const errorMessage = 'Unable to download document';
|
|
@@ -6101,11 +6142,11 @@ function DocumentRenderer(props) {
|
|
|
6101
6142
|
},
|
|
6102
6143
|
"aria-describedby": hasError ? errorMessageId : undefined,
|
|
6103
6144
|
children: [jsxRuntime.jsx("img", {
|
|
6104
|
-
src:
|
|
6145
|
+
src: endpoint,
|
|
6105
6146
|
alt: metadata.fileName,
|
|
6106
6147
|
class: `fjs-${type}-image`
|
|
6107
6148
|
}), jsxRuntime.jsx(DownloadButton, {
|
|
6108
|
-
endpoint:
|
|
6149
|
+
endpoint: endpoint,
|
|
6109
6150
|
fileName: metadata.fileName,
|
|
6110
6151
|
onDownloadError: () => {
|
|
6111
6152
|
setHasError(true);
|
|
@@ -6117,20 +6158,18 @@ function DocumentRenderer(props) {
|
|
|
6117
6158
|
});
|
|
6118
6159
|
}
|
|
6119
6160
|
if (isContentTypePresent && metadata.contentType.toLowerCase() === 'application/pdf' && isInViewport) {
|
|
6120
|
-
return jsxRuntime.
|
|
6161
|
+
return jsxRuntime.jsx("div", {
|
|
6121
6162
|
class: singleDocumentContainerClassName,
|
|
6122
6163
|
style: {
|
|
6123
6164
|
maxHeight
|
|
6124
6165
|
},
|
|
6125
6166
|
"aria-describedby": hasError ? errorMessageId : undefined,
|
|
6126
|
-
children:
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
errors: [errorMessage]
|
|
6133
|
-
}) : null]
|
|
6167
|
+
children: jsxRuntime.jsx(PdfRenderer, {
|
|
6168
|
+
url: endpoint,
|
|
6169
|
+
fileName: metadata.fileName,
|
|
6170
|
+
onError: () => setHasError(true),
|
|
6171
|
+
errorMessageId: errorMessageId
|
|
6172
|
+
})
|
|
6134
6173
|
});
|
|
6135
6174
|
}
|
|
6136
6175
|
return jsxRuntime.jsxs("div", {
|
|
@@ -6146,7 +6185,7 @@ function DocumentRenderer(props) {
|
|
|
6146
6185
|
errors: [errorMessage]
|
|
6147
6186
|
}) : null]
|
|
6148
6187
|
}), jsxRuntime.jsx(DownloadButton, {
|
|
6149
|
-
endpoint:
|
|
6188
|
+
endpoint: endpoint,
|
|
6150
6189
|
fileName: metadata.fileName,
|
|
6151
6190
|
onDownloadError: () => {
|
|
6152
6191
|
setHasError(true);
|
|
@@ -6226,27 +6265,18 @@ function useInViewport(ref) {
|
|
|
6226
6265
|
}
|
|
6227
6266
|
|
|
6228
6267
|
/**
|
|
6229
|
-
*
|
|
6230
|
-
*
|
|
6231
|
-
* @
|
|
6232
|
-
* @param {string} options.baseUrl
|
|
6233
|
-
* @param {string} options.documentId
|
|
6234
|
-
* @param {string} [options.contentHash]
|
|
6235
|
-
*
|
|
6236
|
-
* @returns {string}
|
|
6268
|
+
* @template T
|
|
6269
|
+
* @param {() => T} fn - Function to execute
|
|
6270
|
+
* @returns {T | null}
|
|
6237
6271
|
*/
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
const finalUrl = new URL(baseUrl.replace(DOCUMENT_ID_PLACEHOLDER, documentId));
|
|
6245
|
-
if (contentHash !== undefined) {
|
|
6246
|
-
finalUrl.searchParams.set('contentHash', contentHash);
|
|
6272
|
+
const tryCatch = fn => {
|
|
6273
|
+
try {
|
|
6274
|
+
return fn();
|
|
6275
|
+
} catch (error) {
|
|
6276
|
+
console.error(error);
|
|
6277
|
+
return null;
|
|
6247
6278
|
}
|
|
6248
|
-
|
|
6249
|
-
}
|
|
6279
|
+
};
|
|
6250
6280
|
|
|
6251
6281
|
/**
|
|
6252
6282
|
* This file must not be changed or exchanged.
|
|
@@ -6405,7 +6435,7 @@ class FormFields {
|
|
|
6405
6435
|
}
|
|
6406
6436
|
}
|
|
6407
6437
|
|
|
6408
|
-
const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression', 'url', 'dataSource', 'columnsExpression', 'expression', 'multiple', 'accept', '
|
|
6438
|
+
const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression', 'url', 'dataSource', 'columnsExpression', 'expression', 'multiple', 'accept', 'title'];
|
|
6409
6439
|
const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text', 'content', 'url', 'title'];
|
|
6410
6440
|
|
|
6411
6441
|
/**
|