@bigbinary/neeto-folders-frontend 1.2.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # neeto-folders-nano
2
2
 
3
- The `neeto-folders-nano` acts as the source of truth for the new nano's structure,
4
- configs, data etc.
3
+ The `neeto-folders-nano` acts as the source of truth for the new nano's
4
+ structure, configs, data etc.
5
5
 
6
6
  ## Contents
7
7
 
@@ -37,13 +37,7 @@ configs, data etc.
37
37
  bundle install
38
38
  ```
39
39
 
40
- 3. Add this line to your application's `config/routes.rb` file
41
-
42
- ```ruby
43
- mount NeetoFoldersEngine::Engine => "/neeto_folders_engine"
44
- ```
45
-
46
- 4. Add required migrations in the `db/migrate` folder. Run the following
40
+ 3. Add required migrations in the `db/migrate` folder. Run the following
47
41
  commands to copy the migrations from the engine to the host application.
48
42
 
49
43
  ```shell
@@ -53,23 +47,60 @@ configs, data etc.
53
47
 
54
48
  #### Usage
55
49
 
56
- 1. Replace NeetoFoldersNano with your project name
50
+ 1. Define the folder model in your application by extending the
51
+ `NeetoFoldersEngine::Folder` base class. Below is the sample code in
52
+ NeetoRecord that defines a `RecordingFolder` model by extending the
53
+ `NeetoFoldersEngine::Folder` to manage recordings.
57
54
 
58
- Create a `script.rb` file in the project root and paste the script from the
59
- following file.
55
+ ```ruby
56
+ class RecordingFolder < NeetoFoldersEngine::Folder
57
+ has_many :recordings, -> { unscope(where: :deleted_at) }, foreign_key: :folder_id, dependent: :nullify
58
+ ```
60
59
 
61
- [Replace project name script](./docs/engine/replace-project-name-script.md)
60
+ `NeetoFoldersEngine` also expects a instance method `items` to be defined in
61
+ the extended class. This enables the `NeetoFoldersEngine` to keep track of
62
+ the count of items in the folder. Below is a sample code from NeetoRecord.
62
63
 
63
- 2. Run the file using the following command:
64
+ ```ruby
65
+ def items
66
+ recordings
67
+ end
68
+ ```
64
69
 
65
- ```shell
66
- ruby script.rb
70
+ 2. Include the `NeetoFoldersEngine::Folderable` in the model which should belong
71
+ to a folder. Order of include is important. Include `Folderable` after
72
+ `Deletable` from neeto-commons-backend to allow `Folderable` to override the
73
+ `soft_delete` method.
74
+
75
+ ```ruby
76
+ include NeetoFoldersEngine::Folderable
67
77
  ```
68
78
 
69
- Notes ⚠️
79
+ 3. `NeetoFoldersEngine` also exposes a controller class
80
+ `NeetoFoldersEngine::FoldersController` with `index`, `show`, `create`,
81
+ `update`, `destroy`, `bulk_update`, `bulk_destroy`, and `reorder` actions to
82
+ manage folders. The host application can extend this class to manage their
83
+ folders. Make sure the routes are properly configured to direct to these
84
+ actions.
70
85
 
71
- - Don't commit this file.
72
- - Project name should be given in PascalCase.
86
+ Similar to the `RecordingFolder < NeetoFoldersEngine::Folder`, the
87
+ `NeetoFoldersEngine::FoldersController` base controller expects a `folders`
88
+ method to be defined in the extended class that allows the controller to
89
+ target folder instances that belongs to a particular type. Given below is
90
+ sample definition in NeetoRecord which extracts recording folders that should
91
+ be managed by the extended controller.
92
+
93
+ ```ruby
94
+ class Api::V1::FoldersController < NeetoFoldersEngine::FoldersController
95
+
96
+ private
97
+
98
+ def folders
99
+ @_folders ||= @organization.recording_folders.includes(:recordings)
100
+ end
101
+ end
102
+
103
+ ```
73
104
 
74
105
  ### Frontend package
75
106
 
@@ -82,21 +113,255 @@ Notes ⚠️
82
113
  ```
83
114
 
84
115
  ### Instructions for development
85
- Check the [Frontend package development guide](https://neeto-engineering.neetokb.com/p/a-d34cb4b0) for step-by-step instructions to develop the frontend package.
116
+
117
+ Check the
118
+ [Frontend package development guide](https://neeto-engineering.neetokb.com/p/a-d34cb4b0)
119
+ for step-by-step instructions to develop the frontend package.
86
120
 
87
121
  #### Usage
88
122
 
89
- 1. Import `WelcomeScreen` component from "@bigbinary/neeto-folders-frontend"
123
+ `neeto-folders-frontend` exports a set of components, hooks, utils and constants
124
+ to be integrated in the host application.
125
+
126
+ Most of the above exports accepts a configuration object with certain
127
+ properties. Given below is the structure of default `config` object. You can
128
+ pass your own config object as argument or props to customize behaviors that
129
+ suits the host product. Define this constant in a constant file and customize
130
+ certain properties such as params as necessary.
131
+
132
+ ```js
133
+ {
90
134
 
91
- ```javascript
92
- import React from "react";
135
+ type: "FOLDER", // A unique type key for query keys.
136
+ maxDepth: 2, // Maximum allowed depth for folder tree
137
+ folderPath: "/folders/:folderId", // Path for handling URL redirections and params matching.
138
+ invalidationKeys: [], // For invalidation purposes. Keys in this array will be invalidated along with folders.
139
+ reorderMode: "rearrange", // If reorder pane should mount in positional `reorder` mode or simple `rearrange` mode.
140
+ // Taxonomy
141
+ labels: {
142
+ folder: t("common.folder"),
143
+ folders: t("common.folders"),
144
+ items: t("common.items"),
145
+ items: t("common.items"),
146
+ }
147
+ params: {}, // Params to be passed to APIs along with other params. Can be used for sorting and similar.
148
+ api: { // Folder CRUD methods.
149
+ fetch: noop,
150
+ get: noop,
151
+ create: noop,
152
+ update: noop,
153
+ destroy: noop,
154
+ bulkUpdate: noop,
155
+ bulkDestroy: noop,
156
+ }
157
+ }
158
+ ```
93
159
 
94
- import { WelcomeScreen } from "@bigbinary/neeto-folders-frontend";
160
+ #### Components
95
161
 
96
- const App = () => <WelcomeScreen />;
162
+ ```js
163
+ import * as components from "@bigbinary/neeto-folders-frontend/components";
164
+ ```
97
165
 
98
- export default App;
99
- ```
166
+ 1. `FoldersContext`: This component renders all alerts and panes related to
167
+ folders. Make sure this component is included in some part of your
168
+ application.
169
+
170
+ ###### Props:
171
+
172
+ - `config`: A config object to customize the folders behavior.
173
+
174
+ Sample usage:
175
+
176
+ ```jsx
177
+ import { FoldersContext } from "@bigbinary/neeto-folders-frontend/components";
178
+ // ....
179
+ <FoldersContext config={foldersConfig}>
180
+ <ApplicationComponent>
181
+ </FoldersContext>
182
+ ```
183
+
184
+ 2. `FoldersTree`: This component renders the folders in tree a tree structure.
185
+
186
+ ###### Props:
187
+
188
+ - `config`: A config object to customize the folders behavior.
189
+
190
+ Sample usage:
191
+
192
+ ```jsx
193
+ import { FoldersTree } from "@bigbinary/neeto-folders-frontend/components";
194
+ // ....
195
+ <FoldersTree config={foldersConfig} />;
196
+ ```
197
+
198
+ 3. `FoldersList`: Component renders list of folders. If no folder is
199
+ selected/active, renders list of root folders. If inside a selected folder,
200
+ renders list of sub-folders. The active folder is identified based on the
201
+ param in the URL that matches the `folderPath` in the `config` object.
202
+
203
+ ###### Props:
204
+
205
+ - `config`: A config object to customize the folders behavior.
206
+
207
+ - `selection`: An array of folder ids indicating id of selected folders for
208
+ bulk selection.
209
+
210
+ - `onSelect`: Callback triggered when checkbox is selected for a folder item
211
+ for bulk selection.
212
+
213
+ Sample usage:
214
+
215
+ ```jsx
216
+ import { FoldersList } from "@bigbinary/neeto-folders-frontend/components";
217
+ // ....
218
+ <FoldersList
219
+ config={foldersConfig}
220
+ onSelect={onSelectFolder}
221
+ selection={folderSelection}
222
+ />;
223
+ ```
224
+
225
+ 4. `MoveToFoldersPane`: This component can be used in host applications to move
226
+ items to a folder. Component renders current list of folders in pane with
227
+ radio buttons and invokes callbacks for folder selections.
228
+
229
+ ###### Props:
230
+
231
+ - `isOpen`: Boolean value that controls pane visibility.
232
+
233
+ - `item`: An item object that is to be moved to the folder.
234
+
235
+ - `config`: A config object to customize the folders behavior.
236
+
237
+ - `submitButtonProps`: Pane "Submit" button overrides.
238
+
239
+ - `cancelButtonProps`: Pane "Cancel" button overrides.
240
+
241
+ - `removeButtonProps`: Pane "Remove from folder" button overrides. Note that
242
+ the button will be hidden unless the `onRemove` prop is supplied.
243
+
244
+ - `onSubmit(folderId)`: Callback invoked with id of selected folder on
245
+ submit.
246
+
247
+ - `onClose()`: Callback invoked when the pane is closed.
248
+
249
+ - `onRemove()`: Callback invoked when the Remove from folder button is
250
+ pressed. Note that the button will be hidden unless this prop is supplied.
251
+
252
+ - `onSelect`: Callback triggered when checkbox is selected for a folder item
253
+ for bulk selection.
254
+
255
+ Sample usage:
256
+
257
+ ```jsx
258
+ import { MoveToFoldersPane } from "@bigbinary/neeto-folders-frontend/components";
259
+ // ....
260
+ <MoveToFoldersPane
261
+ item={itemToMove}
262
+ onSelect={onSelectFolder}
263
+ selection={folderSelection}
264
+ />;
265
+ ```
266
+
267
+ #### Hooks
268
+
269
+ ```js
270
+ import * as hooks from "@bigbinary/neeto-folders-frontend/hooks";
271
+ ```
272
+
273
+ 1. `useFolders(config)`: Hook that return the data for all folders in tree
274
+ structure.
275
+
276
+ ###### Arguments:
277
+
278
+ - `config`: A config object to customize the folders behavior.
279
+
280
+ ###### Returns:
281
+
282
+ - `isLoading`: `true` when data is being fetched for active folder. `false`
283
+ otherwise.
284
+
285
+ - `folders`: Data of all folders of given type in tree structure.
286
+
287
+ 2. `useFolder(config)`: Hook that return the data related to current active
288
+ folder based on URL param.
289
+
290
+ ###### Arguments:
291
+
292
+ - `config`: A config object to customize the folders behavior.
293
+
294
+ ###### Returns:
295
+
296
+ - `isLoading`: `true` when data is being fetched for active folder. `false`
297
+ otherwise.
298
+
299
+ - `folderId`: SID of the current active folder based on URL param.
300
+
301
+ - `folder`: Data of the current folder if exists.
302
+
303
+ 3. `useFolderActions(config)`: Hook that return a set of callbacks to trigger
304
+ actions from host application.
305
+
306
+ ###### Arguments:
307
+
308
+ - `config`: A config object to customize the folders behavior.
309
+
310
+ ###### Returns:
311
+
312
+ - `isPending`: `true` when action is in progress. `false` otherwise.
313
+
314
+ - `onAdd()`: Initiates the folder create action.
315
+
316
+ - `onEdit(folder)`: Initiates the folder edit action. Accepts `folder` data
317
+ as argument.
318
+
319
+ - `onMove(folder)`: Initiates the folder edit action. Accepts `folder` data
320
+ as argument.
321
+
322
+ - `onDelete(folder)`: Initiates the folders delete action. Accepts `folder`
323
+ data as argument.
324
+
325
+ - `onReorder()`: Initiates the reorder folder action. Opens the "Reorder"
326
+ pane.
327
+
328
+ #### Utils
329
+
330
+ ```js
331
+ import * as utils from "@bigbinary/neeto-folders-frontend/utils";
332
+ ```
333
+
334
+ 1. pathToFolder(folders, folderId):
335
+
336
+ ###### Arguments:
337
+
338
+ - `folders`: Folders data in tree structure, returned by the `useFolders`
339
+ hook.
340
+
341
+ - `folderId`: Target folder id.
342
+
343
+ Returns an flattened array of folders from root folder to current folder with
344
+ id `folderId`. Useful for showing breadcrumbs and similar.
345
+
346
+ #### Constants
347
+
348
+ ```js
349
+ import * as constants from "@bigbinary/neeto-folders-frontend/constants";
350
+ ```
351
+
352
+ 1. `QUERY_KEYS`: Use query keys to target React Query actions such as
353
+ invalidations.
354
+
355
+ - `[QUERY_KEYS.FOLDERS]`: Targets every query related to folders.
356
+
357
+ - `[QUERY_KEYS.FOLDERS, config.folderType]`: Targets every query related to
358
+ folders of particular type.
359
+
360
+ - `[QUERY_KEYS.FOLDERS, config.folderType, QUERY_KEYS.LIST]`: Targets folders
361
+ list.
362
+
363
+ - `[QUERY_KEYS.FOLDERS, config.folderType, QUERY_KEYS.DETAILS, folderId]`:
364
+ Target folder details of a folder with id `folderId`
100
365
 
101
366
  ## Instructions for Publishing
102
367
 
@@ -5,32 +5,40 @@
5
5
  "edit": "Edit",
6
6
  "move": "Move",
7
7
  "save": "Save",
8
+ "name": "Name",
9
+ "folder": "Folder",
10
+ "folders": "Folders",
11
+ "item": "Item",
8
12
  "items": "Items"
9
13
  },
14
+
10
15
  "createFolder": {
11
- "parentInfo": "Leave the option empty to create folder at the root level",
12
- "parentTitle": "Parent folder"
16
+ "parentInfo": "Leave the option empty to create {{ folder }} at the root level",
17
+ "parentTitle": "Parent {{ folder }}"
13
18
  },
14
19
  "deleteFolder": {
15
- "info": "Are you sure you want to delete the folder <strong>{{name, anyCase}}</strong>?",
16
- "title": "Delete folder"
20
+ "info": "Are you sure you want to delete the {{ folder }} <strong>{{name, anyCase}}</strong>?",
21
+ "title": "Delete {{ folder }}"
17
22
  },
18
23
  "folders": {
19
- "title": "Folders",
20
- "add": "Add new folder",
21
- "edit": "Edit folder",
22
- "name": "Folder name",
23
- "subfolderCount_one": "{{count}} sub folder",
24
- "subfolderCount_other": "{{count}} sub folders",
25
- "noFolders": "No folders to show"
24
+ "title": "{{ folders }}",
25
+ "add": "Add new {{ folder }}",
26
+ "edit": "Edit {{ folder }}",
27
+ "name": "{{ folder }} name",
28
+ "subfolderCount": "{{count}} sub {{ folders }}",
29
+ "noFolders": "No {{ folder }} to show"
26
30
  },
27
31
  "moveToFolder": {
28
- "depthExceeded": "Cannot move to this folder. Maximum {{maxDepth}} nested folders are allowed.",
29
- "notAllowed": "You cannot move to this folder.",
30
- "remove": "Remove from folder",
31
- "title": "Move to folder"
32
+ "depthExceeded": "Cannot move to this {{ folder }}. Maximum {{maxDepth}} nested {{ folders }} are allowed.",
33
+ "notAllowed": "You cannot move to this {{ folder }}.",
34
+ "remove": "Remove from {{ folder }}",
35
+ "title": "Move to {{ folder }}"
32
36
  },
33
37
  "reorderFolder": {
34
- "title": "Reorder folders"
38
+ "title": "Reorder {{ folders }}"
39
+ },
40
+
41
+ "errors": {
42
+ "blank": "{{entity}} cannot be blank"
35
43
  }
36
44
  }