@project-sunbird/collection-editor-react 0.1.0 → 0.1.2

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 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.
@@ -5,7 +5,7 @@ export declare function readHierarchy(contentId: string): Promise<{
5
5
  rootNode: INode;
6
6
  }>;
7
7
  export declare function updateHierarchy(_contentId: string, nodesModified: Record<string, unknown>, hierarchy: Record<string, unknown>, lastUpdatedBy?: string): Promise<void>;
8
- export declare function publishContent(contentId: string): Promise<void>;
8
+ export declare function publishContent(contentId: string, lastPublishedBy?: string): Promise<void>;
9
9
  export declare function readContent(contentId: string): Promise<Record<string, unknown>>;
10
10
  export declare function sendForReview(contentId: string): Promise<void>;
11
11
  export declare function rejectContent(contentId: string, comment: string): Promise<void>;