Skip to content

Commit 6782b93

Browse files
committed
Merge branch 'main' into thulasizwe/en/canvas
2 parents df8b56f + 96c404d commit 6782b93

File tree

10 files changed

+177
-125
lines changed

10 files changed

+177
-125
lines changed

shesha-reactjs/src/components/customFile/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { FC } from 'react';
2-
import { IUploadFilePayload, IStoredFile } from '@/providers/storedFiles/contexts';
2+
import { IUploadFilePayload } from '@/providers/storedFiles/contexts';
33
import { StoredFilesRendererBase } from '@/components/';
44
import { IInputStyles, IStyleType, useSheshaApplication, useStoredFilesStore } from '@/providers';
55
import { layoutType, listType } from '@/designer-components/attachmentsEditor/attachmentsEditor';
@@ -8,7 +8,6 @@ export interface ICustomFileProps extends IInputStyles {
88
id?: string;
99
ownerId?: string;
1010
uploadFile?: (payload: IUploadFilePayload) => void;
11-
onFileListChanged?: (list: IStoredFile[]) => void;
1211
maxCount?: number;
1312
allowAdd?: boolean;
1413
allowReplace?: boolean;
@@ -60,7 +59,6 @@ export const CustomFile: FC<ICustomFileProps> = (props) => {
6059
downloadZipFile={downloadZipFile}
6160
downloadZip={props.downloadZip}
6261
downloadFile={downloadFile}
63-
onFileListChanged={props.onFileListChanged}
6462
isDownloadingFileListZip={downloadZip}
6563
isDownloadZipSucceeded={downloadZipSuccess}
6664
allowedFileTypes={props?.allowedFileTypes}

shesha-reactjs/src/components/storedFilesRenderer/index.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { FC, ReactNode } from 'react';
1+
import React, { FC } from 'react';
22
import { StoredFilesRendererBase } from '@/components/storedFilesRendererBase';
33
import { useStoredFilesStore } from '@/providers/storedFiles';
44
import { ButtonProps } from 'antd';
@@ -10,7 +10,6 @@ export interface IStoredFilesRendererProps {
1010
isDragger?: boolean;
1111
uploadBtnProps?: ButtonProps;
1212
disabled?: boolean;
13-
noFilesCaption?: ReactNode;
1413
accept?: string[];
1514
layout?: 'vertical' | 'horizontal' | 'grid';
1615
listType?: 'text' | 'thumbnail';
@@ -26,7 +25,6 @@ export const StoredFilesRenderer: FC<IStoredFilesRendererProps> = ({
2625
accept = [],
2726
layout,
2827
listType,
29-
onFileListChanged,
3028
}) => {
3129
const {
3230
fileList,
@@ -47,15 +45,14 @@ export const StoredFilesRenderer: FC<IStoredFilesRendererProps> = ({
4745
deleteFile={deleteFile}
4846
downloadZipFile={downloadZipFile}
4947
downloadFile={downloadFile}
50-
isDownloadingFileListZip={isInProgress && isInProgress.dowloadZip}
51-
isDownloadZipSucceeded={succeeded && succeeded.dowloadZip}
48+
isDownloadingFileListZip={isInProgress?.downloadZip}
49+
isDownloadZipSucceeded={succeeded?.downloadZip}
5250
isDragger={isDragger}
5351
uploadBtnProps={uploadBtnProps}
5452
disabled={disabled}
5553
allowedFileTypes={accept}
5654
layout={layout}
5755
listType={listType}
58-
onFileListChanged={onFileListChanged}
5956
// noFilesCaption={noFilesCaption}
6057
/>
6158
);

shesha-reactjs/src/components/storedFilesRendererBase/index.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ export interface IStoredFilesRendererBaseProps extends IInputStyles {
4343
downloadZipFile?: () => void;
4444
downloadZip?: boolean;
4545
downloadFile: (payload: IDownloadFilePayload) => void;
46-
onFileListChanged?: (list: IStoredFile[]) => void;
4746
validFileTypes?: IUploaderFileTypes[];
4847
maxFileLength?: number;
4948
isDragger?: boolean;
@@ -76,7 +75,6 @@ export const StoredFilesRendererBase: FC<IStoredFilesRendererBaseProps> = ({
7675
uploadFile,
7776
downloadZipFile,
7877
downloadFile,
79-
onFileListChanged,
8078
ownerId,
8179
ownerType,
8280
fetchFilesError,
@@ -214,17 +212,13 @@ export const StoredFilesRendererBase: FC<IStoredFilesRendererBaseProps> = ({
214212
multiple,
215213
fileList,
216214
disabled,
217-
pastable: false,
218215
onChange(info: UploadChangeParam) {
219216
const { status } = info.file;
220217
if (status === 'done') {
221218
message.success(`${info.file.name} file uploaded successfully.`);
222219
} else if (status === 'error') {
223220
message.error(`${info.file.name} file upload failed.`);
224221
}
225-
if (onFileListChanged) {
226-
onFileListChanged(info.fileList);
227-
}
228222
},
229223
onRemove(file) {
230224
showDeleteConfirmation(file);

shesha-reactjs/src/designer-components/attachmentsEditor/attachmentsEditor.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,22 @@ import moment from 'moment';
44
import React from 'react';
55
import { CustomFile } from '@/components';
66
import ConfigurableFormItem from '@/components/formDesigner/components/formItem';
7-
import { DataTypes, IToolboxComponent } from '@/interfaces';
8-
import { IStyleType, useForm, useFormData, useGlobalState, useHttpClient, useSheshaApplication } from '@/providers';
7+
import { IToolboxComponent } from '@/interfaces';
8+
import { IStyleType, useDataContextManagerActions, useForm, useFormData, useGlobalState, useHttpClient, useSheshaApplication } from '@/providers';
99
import { IConfigurableFormComponent, IInputStyles } from '@/providers/form/models';
1010
import {
1111
evaluateValue,
12-
executeScript,
12+
executeScriptSync,
1313
validateConfigurableComponentSettings,
1414
} from '@/providers/form/utils';
1515
import StoredFilesProvider from '@/providers/storedFiles';
16-
import { IStoredFile } from '@/providers/storedFiles/contexts';
1716
import { getSettings } from './settings';
1817
import { migrateCustomFunctions, migratePropertyName, migrateReadOnly } from '@/designer-components/_common-migrations/migrateSettings';
1918
import { migrateVisibility } from '@/designer-components/_common-migrations/migrateVisibility';
2019
import { getFormApi } from '@/providers/form/formApi';
2120
import { migrateFormApi } from '../_common-migrations/migrateFormApi1';
22-
import { containerDefaultStyles, defaultStyles } from './utils';
2321
import { GHOST_PAYLOAD_KEY } from '@/utils/form';
22+
import { containerDefaultStyles, defaultStyles } from './utils';
2423

2524
export type layoutType = 'vertical' | 'horizontal' | 'grid';
2625
export type listType = 'text' | 'thumbnail';
@@ -37,6 +36,7 @@ export interface IAttachmentsEditorProps extends IConfigurableFormComponent, IIn
3736
isDragger?: boolean;
3837
maxHeight?: string;
3938
onFileChanged?: string;
39+
onDownload?: string;
4040
downloadZip?: boolean;
4141
filesLayout?: layoutType;
4242
listType: listType;
@@ -46,48 +46,54 @@ export interface IAttachmentsEditorProps extends IConfigurableFormComponent, IIn
4646
hideFileName?: boolean;
4747
container?: IStyleType;
4848
primaryColor?: string;
49-
removeFieldFromPayload?: boolean;
5049
}
5150

5251
const AttachmentsEditor: IToolboxComponent<IAttachmentsEditorProps> = {
5352
type: 'attachmentsEditor',
5453
isInput: true,
5554
name: 'File list',
5655
icon: <FolderAddOutlined />,
57-
dataTypeSupported: (dataTypeInfo) => dataTypeInfo.dataType === DataTypes.advanced && dataTypeInfo.dataFormat === 'attachmentsEditor',
5856
Factory: ({ model }) => {
5957
const { backendUrl } = useSheshaApplication();
6058
const httpClient = useHttpClient();
6159
const form = useForm();
6260
const { data } = useFormData();
6361
const { globalState, setState: setGlobalState } = useGlobalState();
6462
const { message } = App.useApp();
65-
63+
const pageContext = useDataContextManagerActions()?.getPageContext();
6664
const ownerId = evaluateValue(`${model.ownerId}`, { data: data, globalState });
6765

6866
const enabled = !model.readOnly;
6967

70-
const onFileListChanged = (fileList: IStoredFile[]) => {
71-
if (!model.onFileChanged)
72-
return;
73-
74-
executeScript<void>(model.onFileChanged, {
75-
fileList,
68+
const executeScript = (script, value) => {
69+
executeScriptSync(script, {
70+
value,
7671
data,
7772
form: getFormApi(form),
7873
globalState,
7974
http: httpClient,
8075
message,
8176
moment,
8277
setGlobalState,
78+
pageContext,
8379
});
8480
};
8581

8682
return (
8783
// Add GHOST_PAYLOAD_KEY to remove field from the payload
8884
// File list uses propertyName only for support Required feature
89-
<ConfigurableFormItem model={{ ...model, propertyName: !model.removeFieldFromPayload && model.propertyName ? model.propertyName : `${GHOST_PAYLOAD_KEY}_${model.propertyName}` }}>
85+
<ConfigurableFormItem model={{ ...model, propertyName: model.propertyName || `${GHOST_PAYLOAD_KEY}_${model.id}` }}>
9086
{(value, onChange) => {
87+
const onFileListChanged = (fileList) => {
88+
onChange(fileList);
89+
if (model.onChangeCustom) executeScript(model.onChangeCustom, fileList);
90+
};
91+
92+
const onDownload = (fileList) => {
93+
onChange(fileList);
94+
if (model.onDownload) executeScript(model.onDownload, fileList);
95+
};
96+
9197
return (
9298
<StoredFilesProvider
9399
ownerId={Boolean(ownerId) ? ownerId : Boolean(data?.id) ? data?.id : ''}
@@ -98,7 +104,8 @@ const AttachmentsEditor: IToolboxComponent<IAttachmentsEditorProps> = {
98104
filesCategory={model.filesCategory}
99105
baseUrl={backendUrl}
100106
// used for requered field validation
101-
onChange={onChange}
107+
onChange={onFileListChanged}
108+
onDownload={onDownload}
102109
value={value}
103110
>
104111
<CustomFile
@@ -111,7 +118,6 @@ const AttachmentsEditor: IToolboxComponent<IAttachmentsEditorProps> = {
111118
allowedFileTypes={model.allowedFileTypes}
112119
maxHeight={model.maxHeight}
113120
isDragger={model?.isDragger}
114-
onFileListChanged={onFileListChanged}
115121
downloadZip={model.downloadZip}
116122
filesLayout={model.filesLayout}
117123
listType={model.listType}
@@ -156,7 +162,7 @@ const AttachmentsEditor: IToolboxComponent<IAttachmentsEditorProps> = {
156162
}))
157163
.add<IAttachmentsEditorProps>(6, (prev) => ({ ...prev, listType: !prev.listType ? 'text' : prev.listType, filesLayout: prev.filesLayout ?? 'horizontal' }))
158164
.add<IAttachmentsEditorProps>(7, (prev) => ({ ...prev, desktop: { ...defaultStyles(), container: containerDefaultStyles() }, mobile: { ...defaultStyles() }, tablet: { ...defaultStyles() } }))
159-
.add<IAttachmentsEditorProps>(8, (prev) => ({ ...prev, removeFieldFromPayload: true })),
165+
.add<IAttachmentsEditorProps>(8, (prev) => ({ ...prev, downloadZip: prev.downloadZip || false, propertyName: prev.propertyName ?? '', onChangeCustom: prev.onFileChanged })),
160166
};
161167

162168
export default AttachmentsEditor;

shesha-reactjs/src/designer-components/attachmentsEditor/settings.ts

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export const getSettings = () => {
2222
const pnlShadowStyleId = nanoid();
2323
const customStylePnlId = nanoid();
2424
const pnlFontStyleId = nanoid();
25-
const containerId = nanoid();
2625

2726
return {
2827
components: new DesignerToolbarSettings()
@@ -41,36 +40,18 @@ export const getSettings = () => {
4140
id: commonTabId,
4241
components: [
4342
...new DesignerToolbarSettings()
44-
.addSettingsInput({
43+
.addContextPropertyAutocomplete({
4544
id: nanoid(),
46-
propertyName: 'removeFieldFromPayload',
47-
label: 'Exclude From Form Data',
48-
inputType: 'switch',
49-
tooltip: 'If checked, the field will not be included in the submitted payload',
50-
jsSetting: true,
51-
})
52-
.addContainer({
53-
id: containerId,
54-
propertyName: 'container',
55-
label: 'Container',
45+
propertyName: 'propertyName',
46+
label: 'Property Name',
5647
parentId: commonTabId,
57-
hidden: { _code: 'return getSettingValue(data?.removeFieldFromPayload);', _mode: 'code', _value: false } as any,
58-
components: [
59-
...new DesignerToolbarSettings()
60-
.addContextPropertyAutocomplete({
61-
id: nanoid(),
62-
propertyName: 'propertyName',
63-
label: 'Property Name',
64-
parentId: containerId,
65-
size: 'small',
66-
styledLabel: true,
67-
validate: {
68-
required: true,
69-
},
70-
jsSetting: true,
71-
})
72-
.toJson(),
73-
],
48+
description: "If left empty, the field will not be included in the submitted payload",
49+
size: 'small',
50+
styledLabel: true,
51+
validate: {
52+
required: true,
53+
},
54+
jsSetting: true,
7455
})
7556
.addSettingsInput({
7657
id: nanoid(),
@@ -285,7 +266,7 @@ export const getSettings = () => {
285266
.addSettingsInput({
286267
id: nanoid(),
287268
inputType: 'codeEditor',
288-
propertyName: 'onFileChanged',
269+
propertyName: 'onChangeCustom',
289270
label: 'On File List Changed',
290271
labelAlign: 'right',
291272
parentId: eventsTabId,
@@ -298,6 +279,25 @@ export const getSettings = () => {
298279
functionName: 'onFileListChanged',
299280
useAsyncDeclaration: true,
300281
},
282+
availableConstantsExpression: " return metadataBuilder.object(\"constants\")\r\n .addAllStandard()\r\n .addString(\"value\", \"Component current value\")\r\n .addObject(\"event\", \"Event callback when user input\", undefined)\r\n .build();",
283+
})
284+
.addSettingsInput({
285+
id: nanoid(),
286+
inputType: 'codeEditor',
287+
propertyName: 'onDownload',
288+
label: 'On Download',
289+
labelAlign: 'right',
290+
parentId: eventsTabId,
291+
hidden: false,
292+
description: 'Callback that is triggered when a file is downloaded.',
293+
validate: {},
294+
settingsValidationErrors: [],
295+
wrapInTemplate: true,
296+
templateSettings: {
297+
functionName: 'onDownload',
298+
useAsyncDeclaration: true,
299+
},
300+
availableConstantsExpression: " return metadataBuilder.object(\"constants\")\r\n .addAllStandard()\r\n .addString(\"value\", \"Component current value\")\r\n .addObject(\"event\", \"Event callback when user input\", undefined)\r\n .build();",
301301
})
302302
.toJson(),
303303
],

shesha-reactjs/src/providers/storedFiles/actions.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ export enum StoredFilesActionEnums {
1111
DeleteFileRequest = 'DELETE_FILE_REQUEST',
1212
DeleteFileSuccess = 'DELETE_FILE_SUCCESS',
1313
DeleteFileError = 'DELETE_FILE_ERROR',
14-
DowloadZipRequest = 'DOWLOAD_ZIP_REQUEST',
15-
DowloadZipSuccess = 'DOWLOAD_ZIP_SUCCESS',
16-
DowloadZipError = 'DOWLOAD_ZIP_ERROR',
1714
FetchFileListRequest = 'FETCH_FILE_LIST_REQUEST',
1815
FetchFileListSuccess = 'FETCH_FILE_LIST_SUCCESS',
1916
FetchFileListError = 'FETCH_FILE_LIST_ERROR',
@@ -23,6 +20,8 @@ export enum StoredFilesActionEnums {
2320
OnFileAdded = 'ON_FILE_ADDED',
2421
OnFileDeleted = 'ON_FILE_REMOVED',
2522
InitializeFileList = 'INITIALIZE_FILE_LIST',
23+
UpdateIsDownloadedSuccess = 'UPDATE_IS_DOWNLOADED_SUCCESS',
24+
UpdateAllFilesDownloadedSuccess = 'UPDATE_ALL_FILES_DOWNLOADED_SUCCESS',
2625

2726
/* NEW_ACTION_TYPE_GOES_HERE */
2827
}
@@ -55,29 +54,16 @@ export const uploadFileErrorAction = createAction<IStoredFilesStateContext, ISto
5554

5655
export const deleteFileRequestAction = createAction<IStoredFilesStateContext, string>(
5756
StoredFilesActionEnums.DeleteFileRequest,
58-
(fileIdToDelete) => ({ fileIdToDelete })
57+
(fileIdToDelete) => ({ fileId: fileIdToDelete })
5958
);
6059

6160
export const deleteFileSuccessAction = createAction<IStoredFilesStateContext, string>(
6261
StoredFilesActionEnums.DeleteFileSuccess,
63-
(fileIdToDelete) => ({ fileIdToDelete })
62+
(fileIdToDelete) => ({ fileId: fileIdToDelete })
6463
);
6564
export const deleteFileErrorAction = createAction<IStoredFilesStateContext, string>(
6665
StoredFilesActionEnums.DeleteFileError,
67-
(fileIdToDelete) => ({ fileIdToDelete })
68-
);
69-
70-
export const dowloadZipRequestAction = createAction<IStoredFilesStateContext>(
71-
StoredFilesActionEnums.DowloadZipRequest,
72-
() => ({})
73-
);
74-
export const dowloadZipSuccessAction = createAction<IStoredFilesStateContext>(
75-
StoredFilesActionEnums.DowloadZipSuccess,
76-
() => ({})
77-
);
78-
export const dowloadZipErrorAction = createAction<IStoredFilesStateContext>(
79-
StoredFilesActionEnums.DowloadZipError,
80-
() => ({})
66+
(fileIdToDelete) => ({ fileId: fileIdToDelete })
8167
);
8268

8369
export const fetchFileListRequestAction = createAction<IStoredFilesStateContext>(
@@ -113,12 +99,22 @@ export const onFileAddedAction = createAction<IStoredFilesStateContext, IStoredF
11399

114100
export const onFileDeletedAction = createAction<IStoredFilesStateContext, string>(
115101
StoredFilesActionEnums.OnFileDeleted,
116-
(fileIdToDelete) => ({ fileIdToDelete })
102+
(fileIdToDelete) => ({ fileId: fileIdToDelete })
117103
);
118104

119105
export const initializeFileListAction = createAction<IStoredFilesStateContext, IStoredFile[]>(
120106
StoredFilesActionEnums.InitializeFileList,
121107
(fileList) => ({ fileList })
122108
);
123109

110+
export const updateIsDownloadedByCurrentUser = createAction<IStoredFilesStateContext, string>(
111+
StoredFilesActionEnums.UpdateIsDownloadedSuccess,
112+
(fileId) => ({ fileId })
113+
);
114+
115+
export const updateAllFilesDownloadedByCurrentUser = createAction<IStoredFilesStateContext>(
116+
StoredFilesActionEnums.UpdateAllFilesDownloadedSuccess,
117+
() => ({})
118+
);
119+
124120
/* NEW_ACTION_GOES_HERE */

0 commit comments

Comments
 (0)