hazo_collab_forms 1.1.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/README.md +114 -0
- package/dist/components/collab_form_file_upload.d.ts +65 -0
- package/dist/components/collab_form_file_upload.d.ts.map +1 -0
- package/dist/components/collab_form_file_upload.js +339 -0
- package/dist/components/collab_form_file_upload.js.map +1 -0
- package/dist/components/data_ok_checkbox.d.ts +36 -0
- package/dist/components/data_ok_checkbox.d.ts.map +1 -0
- package/dist/components/data_ok_checkbox.js +26 -0
- package/dist/components/data_ok_checkbox.js.map +1 -0
- package/dist/components/hazo_collab_form_base.d.ts +398 -0
- package/dist/components/hazo_collab_form_base.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_base.js +206 -0
- package/dist/components/hazo_collab_form_base.js.map +1 -0
- package/dist/components/hazo_collab_form_checkbox.d.ts +52 -0
- package/dist/components/hazo_collab_form_checkbox.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_checkbox.js +65 -0
- package/dist/components/hazo_collab_form_checkbox.js.map +1 -0
- package/dist/components/hazo_collab_form_combo.d.ts +91 -0
- package/dist/components/hazo_collab_form_combo.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_combo.js +192 -0
- package/dist/components/hazo_collab_form_combo.js.map +1 -0
- package/dist/components/hazo_collab_form_date.d.ts +71 -0
- package/dist/components/hazo_collab_form_date.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_date.js +251 -0
- package/dist/components/hazo_collab_form_date.js.map +1 -0
- package/dist/components/hazo_collab_form_group.d.ts +40 -0
- package/dist/components/hazo_collab_form_group.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_group.js +151 -0
- package/dist/components/hazo_collab_form_group.js.map +1 -0
- package/dist/components/hazo_collab_form_inputbox.d.ts +44 -0
- package/dist/components/hazo_collab_form_inputbox.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_inputbox.js +64 -0
- package/dist/components/hazo_collab_form_inputbox.js.map +1 -0
- package/dist/components/hazo_collab_form_radio.d.ts +73 -0
- package/dist/components/hazo_collab_form_radio.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_radio.js +65 -0
- package/dist/components/hazo_collab_form_radio.js.map +1 -0
- package/dist/components/hazo_collab_form_set.d.ts +181 -0
- package/dist/components/hazo_collab_form_set.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_set.js +425 -0
- package/dist/components/hazo_collab_form_set.js.map +1 -0
- package/dist/components/hazo_collab_form_textarea.d.ts +43 -0
- package/dist/components/hazo_collab_form_textarea.d.ts.map +1 -0
- package/dist/components/hazo_collab_form_textarea.js +61 -0
- package/dist/components/hazo_collab_form_textarea.js.map +1 -0
- package/dist/components/index.d.ts +23 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +14 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.client.d.ts +7 -0
- package/dist/index.client.d.ts.map +1 -0
- package/dist/index.client.js +7 -0
- package/dist/index.client.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +15 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +62 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/index.d.ts +5 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +5 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/utils/cn.d.ts +12 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/dist/utils/cn.js +15 -0
- package/dist/utils/cn.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/use_chat_messages_check.d.ts +40 -0
- package/dist/utils/use_chat_messages_check.d.ts.map +1 -0
- package/dist/utils/use_chat_messages_check.js +80 -0
- package/dist/utils/use_chat_messages_check.js.map +1 -0
- package/dist/utils/use_collab_chat.d.ts +21 -0
- package/dist/utils/use_collab_chat.d.ts.map +1 -0
- package/dist/utils/use_collab_chat.js +49 -0
- package/dist/utils/use_collab_chat.js.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Hazo Collab Forms
|
|
2
|
+
|
|
3
|
+
Collaboration form elements package built with ES modules.
|
|
4
|
+
|
|
5
|
+
## Package Structure
|
|
6
|
+
|
|
7
|
+
- **Root**: ES module npm package
|
|
8
|
+
- **test-app**: Next.js application for testing the package
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
### Install Dependencies
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This will install dependencies for both the root package and the test-app workspace.
|
|
19
|
+
|
|
20
|
+
### Build Package
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm run build
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This compiles TypeScript to the `dist/` directory with proper ES module exports using `.js` extensions.
|
|
27
|
+
|
|
28
|
+
### Development
|
|
29
|
+
|
|
30
|
+
#### Watch Mode for Package
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm run dev:package
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This watches for changes and rebuilds the package automatically.
|
|
37
|
+
|
|
38
|
+
#### Run Test App
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm run dev:test-app
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This builds the package and starts the Next.js development server.
|
|
45
|
+
|
|
46
|
+
#### Build Test App
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run build:test-app
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This builds both the package and the test-app for production.
|
|
53
|
+
|
|
54
|
+
## Package Configuration
|
|
55
|
+
|
|
56
|
+
### TypeScript Configuration
|
|
57
|
+
|
|
58
|
+
- **tsconfig.json**: Development configuration with bundler module resolution
|
|
59
|
+
- **tsconfig.build.json**: Build configuration with Node16 module resolution for proper ES module output
|
|
60
|
+
|
|
61
|
+
### ES Module Exports
|
|
62
|
+
|
|
63
|
+
All export statements use explicit `.js` extensions as required for ES modules:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
export * from './lib/index.js';
|
|
67
|
+
export * from './components/index.js';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Package Exports
|
|
71
|
+
|
|
72
|
+
The package.json includes proper exports:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"exports": {
|
|
77
|
+
".": {
|
|
78
|
+
"import": "./dist/index.js",
|
|
79
|
+
"types": "./dist/index.d.ts"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Next.js Workspace Integration
|
|
86
|
+
|
|
87
|
+
The test-app is configured to work with the workspace package:
|
|
88
|
+
|
|
89
|
+
1. **webpack alias**: Points `hazo_collab_forms` to the parent `dist/` directory
|
|
90
|
+
2. **module resolution**: Checks both parent and local node_modules
|
|
91
|
+
3. **transpilePackages**: Includes `hazo_collab_forms` in Next.js transpilation
|
|
92
|
+
|
|
93
|
+
## Configuration File
|
|
94
|
+
|
|
95
|
+
The package uses `hazo_collab_forms_config.ini` for configuration. The config file should be placed in:
|
|
96
|
+
|
|
97
|
+
1. The consuming application's root directory (preferred)
|
|
98
|
+
2. The package root directory (fallback for development)
|
|
99
|
+
|
|
100
|
+
## Scripts
|
|
101
|
+
|
|
102
|
+
- `npm run build` - Build the package
|
|
103
|
+
- `npm run dev:package` - Watch mode for package development
|
|
104
|
+
- `npm run dev:test-app` - Build and run test app in dev mode
|
|
105
|
+
- `npm run build:test-app` - Build package and test app for production
|
|
106
|
+
- `npm run clean` - Remove dist directory
|
|
107
|
+
|
|
108
|
+
## Module Resolution Verification
|
|
109
|
+
|
|
110
|
+
After building, verify that all exports in `dist/index.js` use `.js` extensions. The test-app successfully imports and uses the package, confirming proper ES module resolution.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File upload component for collaboration forms
|
|
3
|
+
* Provides drag-and-drop file upload, file list display, and file management
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import type { FileData } from './hazo_collab_form_base.js';
|
|
7
|
+
/**
|
|
8
|
+
* Props for CollabFormFileUpload component
|
|
9
|
+
*/
|
|
10
|
+
export interface CollabFormFileUploadProps {
|
|
11
|
+
/**
|
|
12
|
+
* Field identifier for unique file input ID
|
|
13
|
+
*/
|
|
14
|
+
field_id_final: string;
|
|
15
|
+
/**
|
|
16
|
+
* Whether file upload is enabled
|
|
17
|
+
*/
|
|
18
|
+
accept_files: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Server directory path where files should be saved
|
|
21
|
+
*/
|
|
22
|
+
files_dir?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Maximum file size in bytes
|
|
25
|
+
*/
|
|
26
|
+
max_size?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Minimum number of files
|
|
29
|
+
*/
|
|
30
|
+
min_files?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Maximum number of files
|
|
33
|
+
*/
|
|
34
|
+
max_files?: number;
|
|
35
|
+
/**
|
|
36
|
+
* File type accept attribute
|
|
37
|
+
*/
|
|
38
|
+
file_accept?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Callback after file upload
|
|
41
|
+
*/
|
|
42
|
+
file_processor?: (file_data: FileData, component_ref: React.RefObject<any>) => Promise<void> | void;
|
|
43
|
+
/**
|
|
44
|
+
* Controlled files state
|
|
45
|
+
*/
|
|
46
|
+
files?: FileData[];
|
|
47
|
+
/**
|
|
48
|
+
* Callback when files change
|
|
49
|
+
*/
|
|
50
|
+
on_files_change?: (files: FileData[]) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Component reference to pass to file_processor
|
|
53
|
+
*/
|
|
54
|
+
component_ref?: React.RefObject<any>;
|
|
55
|
+
/**
|
|
56
|
+
* Upload API endpoint
|
|
57
|
+
* Default: '/api/collab-forms/upload-file'
|
|
58
|
+
*/
|
|
59
|
+
upload_endpoint?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Collaboration form file upload component
|
|
63
|
+
*/
|
|
64
|
+
export declare function CollabFormFileUpload({ field_id_final, accept_files, files_dir, max_size, min_files, max_files, file_accept, file_processor, files: controlled_files, on_files_change, component_ref, upload_endpoint, }: CollabFormFileUploadProps): import("react/jsx-runtime").JSX.Element;
|
|
65
|
+
//# sourceMappingURL=collab_form_file_upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collab_form_file_upload.d.ts","sourceRoot":"","sources":["../../src/components/collab_form_file_upload.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAI3D;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,YAAY,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEpG;;OAEG;IACH,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IAEnB;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IAE9C;;OAEG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAErC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA2CD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,cAAc,EACd,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,SAAc,EACd,WAAW,EACX,cAAc,EACd,KAAK,EAAE,gBAAgB,EACvB,eAAe,EACf,aAAa,EACb,eAAiD,GAClD,EAAE,yBAAyB,2CA4S3B"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File upload component for collaboration forms
|
|
3
|
+
* Provides drag-and-drop file upload, file list display, and file management
|
|
4
|
+
*/
|
|
5
|
+
'use client';
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import React, { useRef, useState, useCallback } from 'react';
|
|
8
|
+
import { cn } from '../utils/cn.js';
|
|
9
|
+
import { HiTrash, HiPaperClip, HiPhotograph, HiDocument, HiDocumentText, HiCheckCircle } from 'react-icons/hi';
|
|
10
|
+
import { FaSpinner } from 'react-icons/fa';
|
|
11
|
+
/**
|
|
12
|
+
* Get file icon based on file type
|
|
13
|
+
*/
|
|
14
|
+
function get_file_icon(file_type, file_name) {
|
|
15
|
+
const extension = file_name.split('.').pop()?.toLowerCase() || '';
|
|
16
|
+
const mime_type = file_type.toLowerCase();
|
|
17
|
+
// Image types
|
|
18
|
+
if (mime_type.startsWith('image/') || ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(extension)) {
|
|
19
|
+
return _jsx(HiPhotograph, { className: "h-8 w-8 text-blue-500" });
|
|
20
|
+
}
|
|
21
|
+
// PDF
|
|
22
|
+
if (mime_type === 'application/pdf' || extension === 'pdf') {
|
|
23
|
+
return _jsx(HiDocument, { className: "h-8 w-8 text-red-500" });
|
|
24
|
+
}
|
|
25
|
+
// Document types
|
|
26
|
+
if (mime_type.includes('document') ||
|
|
27
|
+
mime_type.includes('text') ||
|
|
28
|
+
['doc', 'docx', 'txt', 'rtf', 'odt'].includes(extension)) {
|
|
29
|
+
return _jsx(HiDocumentText, { className: "h-8 w-8 text-green-500" });
|
|
30
|
+
}
|
|
31
|
+
// Default
|
|
32
|
+
return _jsx(HiPaperClip, { className: "h-8 w-8 text-gray-500" });
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Format file size for display
|
|
36
|
+
*/
|
|
37
|
+
function format_file_size(bytes) {
|
|
38
|
+
if (bytes === 0)
|
|
39
|
+
return '0 Bytes';
|
|
40
|
+
const k = 1024;
|
|
41
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
42
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
43
|
+
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Collaboration form file upload component
|
|
47
|
+
*/
|
|
48
|
+
export function CollabFormFileUpload({ field_id_final, accept_files, files_dir, max_size, min_files, max_files = 10, file_accept, file_processor, files: controlled_files, on_files_change, component_ref, upload_endpoint = '/api/collab-forms/upload-file', }) {
|
|
49
|
+
const file_input_ref = useRef(null);
|
|
50
|
+
const [internal_files, set_internal_files] = useState([]);
|
|
51
|
+
const [is_dragging, set_is_dragging] = useState(false);
|
|
52
|
+
const [upload_errors, set_upload_errors] = useState({});
|
|
53
|
+
const [uploading_files, set_uploading_files] = useState(new Set());
|
|
54
|
+
const [processing_files, set_processing_files] = useState(new Set());
|
|
55
|
+
const [processed_files, set_processed_files] = useState(new Set());
|
|
56
|
+
// Use controlled files if provided, otherwise use internal state
|
|
57
|
+
const files = controlled_files !== undefined ? controlled_files : internal_files;
|
|
58
|
+
const is_controlled = controlled_files !== undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Update files state
|
|
61
|
+
*/
|
|
62
|
+
const update_files = useCallback((new_files) => {
|
|
63
|
+
if (!is_controlled) {
|
|
64
|
+
set_internal_files(new_files);
|
|
65
|
+
}
|
|
66
|
+
if (on_files_change) {
|
|
67
|
+
on_files_change(new_files);
|
|
68
|
+
}
|
|
69
|
+
}, [is_controlled, on_files_change]);
|
|
70
|
+
/**
|
|
71
|
+
* Validate file before upload
|
|
72
|
+
*/
|
|
73
|
+
const validate_file = useCallback((file) => {
|
|
74
|
+
// Check file count
|
|
75
|
+
if (files.length >= max_files) {
|
|
76
|
+
return `Maximum ${max_files} files allowed`;
|
|
77
|
+
}
|
|
78
|
+
// Check file size
|
|
79
|
+
if (max_size && file.size > max_size) {
|
|
80
|
+
return `File size exceeds maximum of ${format_file_size(max_size)}`;
|
|
81
|
+
}
|
|
82
|
+
// Check file type (if file_accept is specified)
|
|
83
|
+
if (file_accept) {
|
|
84
|
+
const accept_patterns = file_accept.split(',').map((p) => p.trim());
|
|
85
|
+
const file_extension = '.' + file.name.split('.').pop()?.toLowerCase();
|
|
86
|
+
const file_mime = file.type;
|
|
87
|
+
const matches = accept_patterns.some((pattern) => {
|
|
88
|
+
if (pattern.startsWith('.')) {
|
|
89
|
+
// Extension match
|
|
90
|
+
return file_extension === pattern.toLowerCase();
|
|
91
|
+
}
|
|
92
|
+
else if (pattern.includes('/*')) {
|
|
93
|
+
// MIME type wildcard (e.g., "image/*")
|
|
94
|
+
const base_type = pattern.split('/')[0];
|
|
95
|
+
return file_mime.startsWith(base_type + '/');
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Exact MIME type match
|
|
99
|
+
return file_mime === pattern;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
if (!matches) {
|
|
103
|
+
return `File type not allowed. Accepted: ${file_accept}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}, [files.length, max_files, max_size, file_accept]);
|
|
108
|
+
/**
|
|
109
|
+
* Upload file to server
|
|
110
|
+
*/
|
|
111
|
+
const upload_file = useCallback(async (file) => {
|
|
112
|
+
const file_id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
113
|
+
const uploading_id = `${file_id}-${file.name}`;
|
|
114
|
+
try {
|
|
115
|
+
set_uploading_files((prev) => new Set(prev).add(uploading_id));
|
|
116
|
+
const form_data = new FormData();
|
|
117
|
+
form_data.append('file', file);
|
|
118
|
+
if (files_dir) {
|
|
119
|
+
form_data.append('files_dir', files_dir);
|
|
120
|
+
}
|
|
121
|
+
const response = await fetch(upload_endpoint, {
|
|
122
|
+
method: 'POST',
|
|
123
|
+
body: form_data,
|
|
124
|
+
});
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
const error_data = await response.json().catch(() => ({ error: 'Upload failed' }));
|
|
127
|
+
throw new Error(error_data.error || `Upload failed: ${response.statusText}`);
|
|
128
|
+
}
|
|
129
|
+
const result = await response.json();
|
|
130
|
+
const file_data = {
|
|
131
|
+
file_path: result.file_path || result.path || '',
|
|
132
|
+
file_name: file.name,
|
|
133
|
+
file_size: file.size,
|
|
134
|
+
file_type: file.type,
|
|
135
|
+
file_id,
|
|
136
|
+
uploaded_at: new Date(),
|
|
137
|
+
};
|
|
138
|
+
// Call file processor if provided
|
|
139
|
+
if (file_processor && component_ref) {
|
|
140
|
+
set_processing_files((prev) => new Set(prev).add(file_data.file_id));
|
|
141
|
+
try {
|
|
142
|
+
await file_processor(file_data, component_ref);
|
|
143
|
+
set_processed_files((prev) => new Set(prev).add(file_data.file_id));
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
set_processing_files((prev) => {
|
|
147
|
+
const next = new Set(prev);
|
|
148
|
+
next.delete(file_data.file_id);
|
|
149
|
+
return next;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
set_upload_errors((prev) => {
|
|
154
|
+
const next = { ...prev };
|
|
155
|
+
delete next[uploading_id];
|
|
156
|
+
return next;
|
|
157
|
+
});
|
|
158
|
+
return file_data;
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
const error_message = error instanceof Error ? error.message : 'Upload failed';
|
|
162
|
+
set_upload_errors((prev) => ({
|
|
163
|
+
...prev,
|
|
164
|
+
[uploading_id]: error_message,
|
|
165
|
+
}));
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
set_uploading_files((prev) => {
|
|
170
|
+
const next = new Set(prev);
|
|
171
|
+
next.delete(uploading_id);
|
|
172
|
+
return next;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}, [files_dir, upload_endpoint, file_processor, component_ref]);
|
|
176
|
+
/**
|
|
177
|
+
* Handle file selection
|
|
178
|
+
*/
|
|
179
|
+
const handle_files_selected = useCallback(async (selected_files) => {
|
|
180
|
+
if (!selected_files || selected_files.length === 0)
|
|
181
|
+
return;
|
|
182
|
+
const files_to_upload = [];
|
|
183
|
+
const errors = {};
|
|
184
|
+
// Validate all files first
|
|
185
|
+
Array.from(selected_files).forEach((file) => {
|
|
186
|
+
const error = validate_file(file);
|
|
187
|
+
if (error) {
|
|
188
|
+
errors[file.name] = error;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
files_to_upload.push(file);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
// Set validation errors
|
|
195
|
+
if (Object.keys(errors).length > 0) {
|
|
196
|
+
set_upload_errors((prev) => ({ ...prev, ...errors }));
|
|
197
|
+
}
|
|
198
|
+
// Upload valid files
|
|
199
|
+
const upload_promises = files_to_upload.map((file) => upload_file(file));
|
|
200
|
+
const uploaded_files = await Promise.all(upload_promises);
|
|
201
|
+
const successful_uploads = uploaded_files.filter((f) => f !== null);
|
|
202
|
+
if (successful_uploads.length > 0) {
|
|
203
|
+
update_files([...files, ...successful_uploads]);
|
|
204
|
+
}
|
|
205
|
+
}, [files, validate_file, upload_file, update_files]);
|
|
206
|
+
/**
|
|
207
|
+
* Handle drag and drop
|
|
208
|
+
*/
|
|
209
|
+
const handle_drag_enter = useCallback((e) => {
|
|
210
|
+
e.preventDefault();
|
|
211
|
+
e.stopPropagation();
|
|
212
|
+
set_is_dragging(true);
|
|
213
|
+
}, []);
|
|
214
|
+
const handle_drag_leave = useCallback((e) => {
|
|
215
|
+
e.preventDefault();
|
|
216
|
+
e.stopPropagation();
|
|
217
|
+
set_is_dragging(false);
|
|
218
|
+
}, []);
|
|
219
|
+
const handle_drag_over = useCallback((e) => {
|
|
220
|
+
e.preventDefault();
|
|
221
|
+
e.stopPropagation();
|
|
222
|
+
}, []);
|
|
223
|
+
const handle_drop = useCallback((e) => {
|
|
224
|
+
e.preventDefault();
|
|
225
|
+
e.stopPropagation();
|
|
226
|
+
set_is_dragging(false);
|
|
227
|
+
handle_files_selected(e.dataTransfer.files);
|
|
228
|
+
}, [handle_files_selected]);
|
|
229
|
+
/**
|
|
230
|
+
* Handle file input change
|
|
231
|
+
*/
|
|
232
|
+
const handle_input_change = useCallback((e) => {
|
|
233
|
+
handle_files_selected(e.target.files);
|
|
234
|
+
// Reset input to allow selecting the same file again
|
|
235
|
+
if (file_input_ref.current) {
|
|
236
|
+
file_input_ref.current.value = '';
|
|
237
|
+
}
|
|
238
|
+
}, [handle_files_selected]);
|
|
239
|
+
/**
|
|
240
|
+
* Handle file delete
|
|
241
|
+
*/
|
|
242
|
+
const handle_delete_file = useCallback((file_id) => {
|
|
243
|
+
const new_files = files.filter((f) => f.file_id !== file_id);
|
|
244
|
+
// Check minimum files constraint
|
|
245
|
+
if (min_files !== undefined && new_files.length < min_files) {
|
|
246
|
+
set_upload_errors((prev) => ({
|
|
247
|
+
...prev,
|
|
248
|
+
delete_error: `Minimum ${min_files} files required`,
|
|
249
|
+
}));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
update_files(new_files);
|
|
253
|
+
set_upload_errors((prev) => {
|
|
254
|
+
const next = { ...prev };
|
|
255
|
+
delete next.delete_error;
|
|
256
|
+
return next;
|
|
257
|
+
});
|
|
258
|
+
}, [files, min_files, update_files]);
|
|
259
|
+
/**
|
|
260
|
+
* Get file URL
|
|
261
|
+
*/
|
|
262
|
+
const get_file_url = useCallback((file_path) => {
|
|
263
|
+
return file_path.startsWith('/')
|
|
264
|
+
? file_path
|
|
265
|
+
: `/api/collab-forms/files/${encodeURIComponent(file_path)}`;
|
|
266
|
+
}, []);
|
|
267
|
+
const accordion_title = files.length > 0 ? `Files (${files.length})` : 'Files';
|
|
268
|
+
// Always render wrapper div to maintain consistent DOM structure
|
|
269
|
+
// This prevents hydration mismatches when accept_files changes between server and client
|
|
270
|
+
return (_jsx("div", { className: "cls_collab_file_upload space-y-2", suppressHydrationWarning: true, children: accept_files ? (
|
|
271
|
+
/* Dynamic import for Accordion - will be loaded by consuming app */
|
|
272
|
+
_jsx(FileUploadAccordion, { field_id_final: field_id_final, title: accordion_title, is_dragging: is_dragging, on_drag_enter: handle_drag_enter, on_drag_leave: handle_drag_leave, on_drag_over: handle_drag_over, on_drop: handle_drop, file_input_ref: file_input_ref, file_accept: file_accept, on_input_change: handle_input_change, files: files, uploading_files: uploading_files, processing_files: processing_files, processed_files: processed_files, upload_errors: upload_errors, get_file_url: get_file_url, on_file_delete: handle_delete_file, get_file_icon: get_file_icon, format_file_size: format_file_size, max_files: max_files })) : null }));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* File upload accordion component with dynamic imports
|
|
276
|
+
*/
|
|
277
|
+
function FileUploadAccordion({ field_id_final, title, is_dragging, on_drag_enter, on_drag_leave, on_drag_over, on_drop, file_input_ref, file_accept, on_input_change, files, uploading_files, processing_files, processed_files, upload_errors, get_file_url, on_file_delete, get_file_icon, format_file_size, max_files, }) {
|
|
278
|
+
const [AccordionComponents, set_accordion_components] = React.useState(null);
|
|
279
|
+
const [is_loading, set_is_loading] = React.useState(true);
|
|
280
|
+
const [is_mounted, set_is_mounted] = React.useState(false);
|
|
281
|
+
// Track client-side mounting to prevent hydration mismatch
|
|
282
|
+
React.useEffect(() => {
|
|
283
|
+
set_is_mounted(true);
|
|
284
|
+
}, []);
|
|
285
|
+
React.useEffect(() => {
|
|
286
|
+
// Only load accordion on client side
|
|
287
|
+
if (!is_mounted)
|
|
288
|
+
return;
|
|
289
|
+
// Dynamic import - components will be resolved by consuming app's bundler
|
|
290
|
+
const load_accordion = async () => {
|
|
291
|
+
try {
|
|
292
|
+
set_is_loading(true);
|
|
293
|
+
// Try to import from consuming app's components directory
|
|
294
|
+
// This path will be resolved by Next.js/webpack in the consuming app
|
|
295
|
+
// @ts-expect-error - These modules are provided by the consuming application
|
|
296
|
+
const accordion_module = await import('@/components/ui/accordion').catch(() => null);
|
|
297
|
+
if (accordion_module) {
|
|
298
|
+
set_accordion_components({
|
|
299
|
+
Accordion: accordion_module.Accordion,
|
|
300
|
+
AccordionItem: accordion_module.AccordionItem,
|
|
301
|
+
AccordionTrigger: accordion_module.AccordionTrigger,
|
|
302
|
+
AccordionContent: accordion_module.AccordionContent,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
console.warn('[CollabFormFileUpload] shadcn Accordion not found. ' +
|
|
307
|
+
'Please install it: npx shadcn@latest add accordion');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
console.warn('[CollabFormFileUpload] Error loading accordion components:', error);
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
set_is_loading(false);
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
load_accordion();
|
|
318
|
+
}, [is_mounted]);
|
|
319
|
+
// Always render consistent structure to prevent hydration mismatch
|
|
320
|
+
// During SSR and initial client render, show empty placeholder
|
|
321
|
+
// After mount and accordion load, show actual content
|
|
322
|
+
if (!is_mounted || is_loading || !AccordionComponents) {
|
|
323
|
+
return (_jsx("div", { className: "cls_collab_file_upload_loading text-sm text-muted-foreground", suppressHydrationWarning: true }));
|
|
324
|
+
}
|
|
325
|
+
const { Accordion, AccordionItem, AccordionTrigger, AccordionContent } = AccordionComponents;
|
|
326
|
+
// Default to open if files exist
|
|
327
|
+
const default_value = files.length > 0 ? 'files' : undefined;
|
|
328
|
+
// Wrap Accordion in div with suppressHydrationWarning to prevent React from checking children
|
|
329
|
+
// The Accordion content may differ between server and client due to dynamic imports
|
|
330
|
+
return (_jsx("div", { suppressHydrationWarning: true, children: _jsx(Accordion, { type: "single", collapsible: true, defaultValue: default_value, className: "w-full", children: _jsxs(AccordionItem, { value: "files", children: [_jsx(AccordionTrigger, { className: "text-sm font-medium", children: title }), _jsx(AccordionContent, { children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: cn('cls_collab_file_drop_zone border-2 border-dashed rounded-md p-6 text-center transition-colors', is_dragging
|
|
331
|
+
? 'border-primary bg-primary/5'
|
|
332
|
+
: 'border-input hover:border-primary/50 hover:bg-muted/50', files.length >= max_files && 'opacity-50 cursor-not-allowed'), onDragEnter: on_drag_enter, onDragLeave: on_drag_leave, onDragOver: on_drag_over, onDrop: on_drop, children: [_jsx("input", { ref: file_input_ref, type: "file", id: `${field_id_final}-file-input`, className: "hidden", accept: file_accept, multiple: true, onChange: on_input_change, disabled: files.length >= max_files }), _jsx("label", { htmlFor: `${field_id_final}-file-input`, className: cn('cursor-pointer block', files.length >= max_files && 'cursor-not-allowed opacity-50'), children: _jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Drag and drop files here, or click to select" }), file_accept && (_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Accepted: ", file_accept] }))] }) })] }), Object.keys(upload_errors).length > 0 && (_jsx("div", { className: "space-y-1", children: Object.entries(upload_errors).map(([key, error]) => (_jsx("p", { className: "text-sm text-destructive", children: error }, key))) })), files.length > 0 && (_jsx("div", { className: "cls_collab_file_list space-y-2", children: _jsx("div", { className: "flex overflow-x-auto gap-2 pb-2", children: files.map((file_data) => {
|
|
333
|
+
const is_uploading = Array.from(uploading_files).some((id) => id.startsWith(file_data.file_id));
|
|
334
|
+
const is_processing = processing_files.has(file_data.file_id);
|
|
335
|
+
const is_processed = processed_files.has(file_data.file_id);
|
|
336
|
+
return (_jsxs("div", { className: "cls_collab_file_item flex-shrink-0 w-24 flex flex-col items-center gap-1 p-2 border rounded-md hover:bg-muted transition-colors", children: [_jsxs("a", { href: get_file_url(file_data.file_path), target: "_blank", rel: "noopener noreferrer", className: cn("flex flex-col items-center gap-1 w-full", is_uploading && "pointer-events-none opacity-50"), "aria-disabled": is_uploading, children: [_jsxs("div", { className: "relative", children: [get_file_icon(file_data.file_type, file_data.file_name), is_processing && (_jsx("div", { className: "absolute -bottom-1 -right-1 bg-background rounded-full p-0.5 shadow-sm border border-border", children: _jsx(FaSpinner, { className: "h-3 w-3 animate-spin text-primary" }) }))] }), _jsx("span", { className: "text-xs text-center truncate w-full", title: file_data.file_name, children: file_data.file_name }), _jsx("span", { className: "text-xs text-muted-foreground", children: format_file_size(file_data.file_size) })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { type: "button", onClick: () => on_file_delete(file_data.file_id), className: "text-destructive hover:text-destructive/80 p-1", disabled: is_uploading, "aria-label": `Delete ${file_data.file_name}`, children: _jsx(HiTrash, { className: "h-4 w-4" }) }), is_processed && !is_processing && (_jsx(HiCheckCircle, { className: "h-4 w-4 text-green-500" }))] }), is_uploading && (_jsx("div", { className: "absolute inset-0 bg-background/50 flex items-center justify-center rounded-md", children: _jsx("div", { className: "text-xs text-muted-foreground", children: "Uploading..." }) }))] }, file_data.file_id));
|
|
337
|
+
}) }) }))] }) })] }) }) }));
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=collab_form_file_upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collab_form_file_upload.js","sourceRoot":"","sources":["../../src/components/collab_form_file_upload.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data OK Checkbox component
|
|
3
|
+
* A checkbox that displays a green checkmark icon when checked and a red radio button off icon when unchecked
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* Props for the DataOkCheckbox component
|
|
8
|
+
*/
|
|
9
|
+
export interface DataOkCheckboxProps {
|
|
10
|
+
/**
|
|
11
|
+
* Whether the checkbox is checked
|
|
12
|
+
*/
|
|
13
|
+
checked: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Callback when checkbox state changes
|
|
16
|
+
*/
|
|
17
|
+
onChange: (checked: boolean) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Optional label for accessibility
|
|
20
|
+
*/
|
|
21
|
+
'aria-label'?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Optional className for the checkbox container
|
|
24
|
+
*/
|
|
25
|
+
className?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether the checkbox is disabled
|
|
28
|
+
*/
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Data OK Checkbox component
|
|
33
|
+
* Displays a green checkmark when checked, light red radio button off when unchecked
|
|
34
|
+
*/
|
|
35
|
+
export declare const DataOkCheckbox: React.ForwardRefExoticComponent<DataOkCheckboxProps & React.RefAttributes<HTMLButtonElement>>;
|
|
36
|
+
//# sourceMappingURL=data_ok_checkbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data_ok_checkbox.d.ts","sourceRoot":"","sources":["../../src/components/data_ok_checkbox.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAErC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,+FAwC1B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data OK Checkbox component
|
|
3
|
+
* A checkbox that displays a green checkmark icon when checked and a red radio button off icon when unchecked
|
|
4
|
+
*/
|
|
5
|
+
'use client';
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { IoCheckmarkCircle, IoRadioButtonOff } from 'react-icons/io5';
|
|
9
|
+
import { cn } from '../utils/cn.js';
|
|
10
|
+
/**
|
|
11
|
+
* Data OK Checkbox component
|
|
12
|
+
* Displays a green checkmark when checked, light red radio button off when unchecked
|
|
13
|
+
*/
|
|
14
|
+
export const DataOkCheckbox = React.forwardRef(({ checked, onChange, 'aria-label': ariaLabel, className, disabled }, ref) => {
|
|
15
|
+
/**
|
|
16
|
+
* Handle click to toggle checkbox state
|
|
17
|
+
*/
|
|
18
|
+
const handle_click = () => {
|
|
19
|
+
if (!disabled) {
|
|
20
|
+
onChange(!checked);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
return (_jsx("button", { ref: ref, type: "button", role: "checkbox", "aria-checked": checked, "aria-label": ariaLabel || (checked ? 'Data OK' : 'Data not OK'), onClick: handle_click, disabled: disabled, suppressHydrationWarning: true, className: cn('cls_data_ok_checkbox flex h-9 w-9 items-center justify-center rounded-md border-0 bg-transparent transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50', className), children: checked ? (_jsx(IoCheckmarkCircle, { className: "h-6 w-6", style: { color: '#10b981' } })) : (_jsx(IoRadioButtonOff, { className: "h-6 w-6", style: { color: '#f87171' } })) }));
|
|
24
|
+
});
|
|
25
|
+
DataOkCheckbox.displayName = 'DataOkCheckbox';
|
|
26
|
+
//# sourceMappingURL=data_ok_checkbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data_ok_checkbox.js","sourceRoot":"","sources":["../../src/components/data_ok_checkbox.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,CAAC;;AAEb,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAgCpC;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAC5C,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE;IAC3E;;OAEG;IACH,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,iBACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,UAAU,kBACD,OAAO,gBACT,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,EAC9D,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,QAAQ,EAClB,wBAAwB,QACxB,SAAS,EAAE,EAAE,CACX,4OAA4O,EAC5O,SAAS,CACV,YAEA,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,iBAAiB,IAChB,SAAS,EAAC,SAAS,EACnB,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAC3B,CACH,CAAC,CAAC,CAAC,CACF,KAAC,gBAAgB,IACf,SAAS,EAAC,SAAS,EACnB,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAC3B,CACH,GACM,CACV,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAC"}
|