@project-sunbird/collection-editor-react 0.1.0 → 0.1.1
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 +238 -0
- package/dist/collection-editor.umd.js +35 -35
- package/dist/index.cjs +34 -34
- package/dist/index.js +2276 -2237
- package/dist/style.css +1 -1
- package/dist/types/editor.d.ts +2 -0
- package/package.json +3 -1
package/README.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# @project-sunbird/collection-editor-react
|
|
2
|
+
|
|
3
|
+
A React component library for the Sunbird Collection Editor — build, organise and manage hierarchical content collections (courses, textbooks, playlists) inside any React 18 application or as a framework-agnostic web component.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @project-sunbird/collection-editor-react
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Peer dependencies** (install separately if not already present):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install react@^18 react-dom@^18
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Quick start — React
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { CollectionEditor } from '@project-sunbird/collection-editor-react';
|
|
25
|
+
import '@project-sunbird/collection-editor-react/dist/style.css';
|
|
26
|
+
|
|
27
|
+
const config = {
|
|
28
|
+
context: {
|
|
29
|
+
authToken: 'your-bearer-token', // omit when using a server-side proxy
|
|
30
|
+
userId: 'user-id',
|
|
31
|
+
sid: 'session-id',
|
|
32
|
+
did: 'device-id',
|
|
33
|
+
channel: 'channel-id',
|
|
34
|
+
pdata: { id: 'your.app.id', ver: '1.0' },
|
|
35
|
+
env: 'collection_editor',
|
|
36
|
+
identifier: 'do_123456789', // content identifier to load
|
|
37
|
+
contentId: 'do_123456789',
|
|
38
|
+
},
|
|
39
|
+
config: {
|
|
40
|
+
mode: 'edit', // 'edit' | 'review' | 'read' | 'sourcingreview'
|
|
41
|
+
objectType: 'Collection',
|
|
42
|
+
primaryCategory: 'Content Playlist',
|
|
43
|
+
maxDepth: 4,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default function App() {
|
|
48
|
+
return (
|
|
49
|
+
<CollectionEditor
|
|
50
|
+
{...config}
|
|
51
|
+
onToolbarEvent={({ action, data }) => {
|
|
52
|
+
if (action === 'back') window.history.back();
|
|
53
|
+
}}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Quick start — Web component (framework-agnostic)
|
|
62
|
+
|
|
63
|
+
Register once (e.g. in your app entry point), then use the custom element anywhere:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { registerCollectionEditor } from '@project-sunbird/collection-editor-react';
|
|
67
|
+
import '@project-sunbird/collection-editor-react/dist/style.css';
|
|
68
|
+
|
|
69
|
+
registerCollectionEditor(); // registers <sb-collection-editor>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<sb-collection-editor id="editor"></sb-collection-editor>
|
|
74
|
+
|
|
75
|
+
<script>
|
|
76
|
+
const el = document.getElementById('editor');
|
|
77
|
+
el.config = JSON.stringify({
|
|
78
|
+
context: { /* ... */ },
|
|
79
|
+
config: { mode: 'edit', objectType: 'Collection' },
|
|
80
|
+
});
|
|
81
|
+
el.onToolbarEvent = (e) => console.log('toolbar:', e.detail);
|
|
82
|
+
</script>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
You can pass a custom tag name to avoid collisions:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
registerCollectionEditor('my-collection-editor');
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## API
|
|
94
|
+
|
|
95
|
+
### `<CollectionEditor>` props
|
|
96
|
+
|
|
97
|
+
| Prop | Type | Required | Description |
|
|
98
|
+
|---|---|---|---|
|
|
99
|
+
| `context` | `IContext` | ✅ | Runtime context — user, session, channel, framework |
|
|
100
|
+
| `config` | `IConfig` | ✅ | Editor behaviour — mode, objectType, depth, category |
|
|
101
|
+
| `metadata` | `Record<string, unknown>` | — | Pre-loaded content metadata |
|
|
102
|
+
| `apiBaseUrl` | `string` | — | Base URL for all API calls. Omit when using a server-side proxy |
|
|
103
|
+
| `onToolbarEvent` | `(e: { action: ToolbarAction; data?: unknown }) => void` | — | Fired on every toolbar button click |
|
|
104
|
+
| `onContentAdded` | `(item: unknown, targetNodeId: string) => void` | — | Fired when content is added from library |
|
|
105
|
+
| `onHierarchySaved` | `(hierarchy: unknown) => void` | — | Fired after a successful hierarchy save |
|
|
106
|
+
| `onError` | `(error: Error) => void` | — | Fired on unrecoverable editor errors |
|
|
107
|
+
|
|
108
|
+
### `IContext`
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
interface IContext {
|
|
112
|
+
authToken: string; // Bearer token; use '' when auth is cookie-based
|
|
113
|
+
userId: string;
|
|
114
|
+
sid: string; // Session ID
|
|
115
|
+
did: string; // Device ID
|
|
116
|
+
channel: string; // Org channel / hashTagId
|
|
117
|
+
pdata: { id: string; ver: string; pid?: string }; // Producer data (telemetry)
|
|
118
|
+
env: string; // e.g. 'collection_editor'
|
|
119
|
+
contentId?: string; // Identifier of the collection to load
|
|
120
|
+
identifier?: string; // Alias for contentId
|
|
121
|
+
framework?: string; // Org framework ID
|
|
122
|
+
targetFWIds?: string[]; // Target framework IDs
|
|
123
|
+
uid?: string;
|
|
124
|
+
rollup?: Record<string, string>;
|
|
125
|
+
tags?: string[];
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### `IConfig`
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
interface IConfig {
|
|
133
|
+
mode: 'edit' | 'review' | 'read' | 'sourcingreview';
|
|
134
|
+
objectType: string; // e.g. 'Collection'
|
|
135
|
+
primaryCategory?: string; // e.g. 'Content Playlist', 'Course'
|
|
136
|
+
framework?: string[];
|
|
137
|
+
targetFWIds?: string[];
|
|
138
|
+
maxDepth?: number; // Max folder nesting depth (default: 4)
|
|
139
|
+
allowContentUnderRoot?: boolean;
|
|
140
|
+
hierarchy?: Record<string, unknown>;
|
|
141
|
+
defaultFields?: Record<string, unknown>;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `ToolbarAction`
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
type ToolbarAction =
|
|
149
|
+
| 'back' | 'preview' | 'saveCollection' | 'publish'
|
|
150
|
+
| 'sendForReview' | 'reject' | 'sendBackForCorrections'
|
|
151
|
+
| 'sourcingApprove' | 'sourcingReject'
|
|
152
|
+
| 'addUnit' | 'addSubUnit'
|
|
153
|
+
| 'manageCollaborators' | 'csvUpload'
|
|
154
|
+
| 'onFormValueChange' | 'onFormStatusChange';
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## API base URL
|
|
160
|
+
|
|
161
|
+
By default all API calls are made relative to the page origin (works with a server-side proxy). To point directly at a backend:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
import { setApiBaseUrl } from '@project-sunbird/collection-editor-react';
|
|
165
|
+
|
|
166
|
+
setApiBaseUrl('https://api.your-sunbird-instance.com');
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Or pass it inline — the editor calls `setApiBaseUrl` automatically on mount:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
<CollectionEditor
|
|
173
|
+
{...config}
|
|
174
|
+
apiBaseUrl="https://api.your-sunbird-instance.com"
|
|
175
|
+
/>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Stores (advanced)
|
|
181
|
+
|
|
182
|
+
The editor exposes its internal Zustand stores for advanced integration scenarios — for example, reading the current tree selection from outside the component:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { useEditorStore, useTreeStore, useLibraryStore } from '@project-sunbird/collection-editor-react';
|
|
186
|
+
|
|
187
|
+
// Inside a React component
|
|
188
|
+
const selectedNodeId = useTreeStore((s) => s.selectedNodeId);
|
|
189
|
+
const editorMode = useEditorStore((s) => s.editorMode);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Styles
|
|
195
|
+
|
|
196
|
+
The stylesheet **must** be imported once in your app — it is not auto-injected:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import '@project-sunbird/collection-editor-react/dist/style.css';
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Development setup
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# Clone the monorepo
|
|
208
|
+
git clone https://github.com/Sunbird-Ed/sunbird-collection-editor.git
|
|
209
|
+
cd sunbird-collection-editor/projects/collection-editor-react
|
|
210
|
+
|
|
211
|
+
# Install
|
|
212
|
+
npm install
|
|
213
|
+
|
|
214
|
+
# Dev server (proxies /action and /api to localhost:3000)
|
|
215
|
+
npm run dev
|
|
216
|
+
|
|
217
|
+
# Build library
|
|
218
|
+
npm run build
|
|
219
|
+
|
|
220
|
+
# Run tests
|
|
221
|
+
npm test
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Compatibility
|
|
227
|
+
|
|
228
|
+
| Dependency | Version |
|
|
229
|
+
|---|---|
|
|
230
|
+
| React | 18.x |
|
|
231
|
+
| React DOM | 18.x |
|
|
232
|
+
| Node | 18+ |
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT — see the repository root for the full licence text.
|