{"id":13527137,"url":"https://github.com/binocarlos/folder-ui","last_synced_at":"2025-09-08T05:32:38.104Z","repository":{"id":57239713,"uuid":"65643721","full_name":"binocarlos/folder-ui","owner":"binocarlos","description":"ui components for a folder editor","archived":false,"fork":false,"pushed_at":"2016-11-11T08:18:34.000Z","size":368,"stargazers_count":6,"open_issues_count":8,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-28T00:13:31.550Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/binocarlos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-14T01:05:53.000Z","updated_at":"2024-03-06T09:15:37.000Z","dependencies_parsed_at":"2022-08-29T21:23:15.984Z","dependency_job_id":null,"html_url":"https://github.com/binocarlos/folder-ui","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binocarlos%2Ffolder-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binocarlos%2Ffolder-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binocarlos%2Ffolder-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binocarlos%2Ffolder-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binocarlos","download_url":"https://codeload.github.com/binocarlos/folder-ui/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232282809,"owners_count":18499325,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T06:01:41.863Z","updated_at":"2025-01-03T02:48:12.314Z","avatar_url":"https://github.com/binocarlos.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"folder-ui\n=========\n\nui components for a folder editor\n\n## install\n\nInstall the module to your project:\n\n```\n$ npm install folder-ui --save\n```\n\n![screenshot1](https://raw.githubusercontent.com/binocarlos/folder-ui/master/screenshot1.png)\n\n![screenshot2](https://raw.githubusercontent.com/binocarlos/folder-ui/master/screenshot2.png)\n\n`folder-ui` provides the following components to be used in a Window Explorer type application:\n\n * TreeViewer - view a hierarchical data structure\n * ChildrenViewer - display a list of items\n * ChildrenToolbar - a toolbar for the children viewer\n * FormViewer - edit a single item\n * FormToolbar - a toolbar for the form viewer\n\nThere are 2 main ways in which you an use this library:\n\n#### external state\n\nIf you have a JSON file or database or something that your data lives in - you can connect that to the `folder-ui` Container components using the database library (more below)\n\n#### existing redux state\n\nIf you already have state in your application that can be used to feed the visual components, you must create your own container components, actions and reducers.  In this case you can skip to the Visual Components section.\n\n## Database Library\n\nIf you are working with external state and want `folder-ui` to handle redux state, you need to provide a database library.  A folder-ui database library is an object with the following properties - all functions:\n\n * `loadTree(done)` - load the tree data\n * `loadChildren(id, done)` - load the children for an item\n * `loadItem(id, done)` - load a single item\n * `addItem(parent, item, done)` - add an item to a parent\n * `saveItem(item, done)` - save an item\n * `deleteItem(id, done)` - delete an item from a parent\n * `pasteItems(mode, parent, items, done)` - paste items, mode is {copy,cut}\n\nIn all cases the callback `done` takes the following signature: `done(err, data)` (i.e. standard node callback style)\n\n## FolderReducer\n\nTo enable multiple `folder-ui` components in the same application - you must create the reducers by passing a `name` - this is used to filter actions so they only modify the correct part of the state tree:\n\n```javascript\nimport { routerReducer } from 'react-router-redux'\nimport FolderReducer from 'folder-ui/lib/reducer'\n\nconst PRODUCTS_NAME = 'products'\nconst SHOPS_NAME = 'shops'\n\nconst reducer = combineReducers({\n  routing: routerReducer,\n  products: FolderReducer('products'),\n  stores: FolderReducer('shops')\n})\n```\n\n## FolderActions\n\nYou create a set of FolderActions for each reducer that you use.\n\nAs well as passing a `name` (which points to the correct reducer for these actions), you must also pass an instance of the database library and some routing information:\n\n```javascript\nimport FolderActions from 'folder-ui/lib/actions'\n\n// both of these modules implement the database library interface\nimport DB1 from './db1'\nimport DB2 from './db2'\n\n// we pass a database and some routing info\n// for how we have built the application\nconst productActions = FolderActions('products', DB1())\n\n// DB2 is a REST api\nconst shopsActions = FolderActions('shops', DB2())\n```\n\nHere - we have created 2 sets of actions, each hooked up to it's own reducer (using the name) and will consume the database instance we passed to it - one for each service.\n\n\n## Container Components\n\nContainer components link the reducer, actions and database and can be used either with [react-router](https://github.com/ReactTraining/react-router) or stand-alone inside your own containers.\n\n * ChildrenTable\n * ChildrenToolbar\n * Form\n * FormToolbar\n * Tree\n\nAll of the container components require `actions` and `handlers` properties.\n\nYou can use the `ContainerFactory` function from `tools` to wrap the container components.  We also use the Wrapper components to contain the Tree on the left and the Toolbar above the main content.\n\n```javascript\nimport React from 'react'\nimport { Route, IndexRoute } from 'react-router'\n\nimport TreeWrapper from 'folder-ui/lib/components/TreeWrapper'\nimport ToolbarWrapper from 'folder-ui/lib/components/ToolbarWrapper'\n\nimport Tree from 'folder-ui/lib/containers/Tree'\nimport ChildrenToolbar from 'folder-ui/lib/containers/ChildrenToolbar'\nimport ChildrenTable from 'folder-ui/lib/containers/ChildrenTable'\nimport FormToolbar from 'folder-ui/lib/containers/FormToolbar'\nimport Form from 'folder-ui/lib/containers/Form'\n\nimport { ContainerFactory } from 'folder-ui/lib/tools'\nimport Schema from 'folder-ui/lib/schema'\nimport FolderActions from 'folder-ui/lib/actions'\n\nimport AppWrapper from './AppWrapper'\nimport Home from './Home'\n\nimport DB from './db'\nimport RouteInfo from './routeinfo'\nimport { PRODUCT_TYPES, PRODUCT_TABLE_FIELDS, PRODUCT_LIBRARY } from './schema'\n\n// Wrap the left hand sidebar wrapper with a wider width\nconst NavWrapper = ContainerFactory({\n  width:250\n})(TreeWrapper)\n\nconst productRoutes = RouteInfo({\n  path:'products'\n})\n\nconst productActions = FolderActions('products', DB())\nconst productSchema = Schema({\n  types:PRODUCT_TYPES,\n  tableFields:PRODUCT_TABLE_FIELDS,\n  library:PRODUCT_LIBRARY\n})\nconst productFactory = ContainerFactory({\n  actions:productActions,\n  handlers:productRoutes.handlers,\n  info:productRoutes.info\n})\nconst productContainers = {\n  tree:productFactory(Tree),\n  childrenToolbar:productFactory(ChildrenToolbar, {\n    getChildTypes:productSchema.getChildTypes\n  }),\n  childrenTable:productFactory(ChildrenTable, {\n    fields:productSchema.getTableFields(),\n    showCheckboxes:true,\n    showHeader:false,\n    multiSelectable:true\n  }),\n  formToolbar:productFactory(FormToolbar, {\n    getSchema:productSchema.getSchema\n  }),\n  form:productFactory(Form, {\n    getSchema:productSchema.getSchema,\n    getLibrary:productSchema.getLibrary\n  })\n}\nconst productViews = {\n  tree:{\n    sidebar: productContainers.tree,\n    main: ToolbarWrapper\n  },\n  view:{\n    toolbar: productContainers.childrenToolbar,\n    main: productContainers.childrenTable\n  },\n  edit:{\n    toolbar: productContainers.formToolbar,\n    main: productContainers.form\n  }\n}\n\nconst Routes = (opts = {}) =\u003e {\n  return (\n    \u003cRoute path=\"/\" component={AppWrapper}\u003e\n      \u003cIndexRoute component={Home} /\u003e\n      \u003cRoute component={NavWrapper}\u003e\n        \u003cRoute path=\"products\" components={productViews.tree}\u003e\n          \u003cIndexRoute components={productViews.view} /\u003e\n          \u003cRoute path=\"view/:id\" components={productViews.view} /\u003e\n          \u003cRoute path=\"delete/:parent/:ids\" components={productViews.view} /\u003e\n          \u003cRoute path=\"edit/:id\" components={productViews.edit} /\u003e\n          \u003cRoute path=\"edit/:parent/:id\" components={productViews.edit} /\u003e\n          \u003cRoute path=\"add/:parent/:type\" components={productViews.edit} /\u003e\n        \u003c/Route\u003e\n      \u003c/Route\u003e\n    \u003c/Route\u003e\n  )\n}\n\nexport default Routes\n```\n\n## Templates\n\nThe whole of the above setup is wrapped up in a template which you can use as follows:\n\n```javascript\nimport React from 'react'\nimport { Route, IndexRoute } from 'react-router'\n\nimport BasicTemplate from '../src/templates/basic'\n\nimport AppWrapper from './AppWrapper'\nimport Home from './Home'\n\nimport DB from './db'\nimport { TYPES, TABLE_FIELDS, LIBRARY } from './schema'\n\nconst ProductRoutes = BasicTemplate({\n  types:TYPES,\n  tableFields:TABLE_FIELDS,\n  library:LIBRARY,\n  name:'products',\n  path:'products',\n  db:DB()\n})\n\nconst ShopRoutes = BasicTemplate({\n  types:TYPES,\n  tableFields:TABLE_FIELDS,\n  library:LIBRARY,\n  name:'shops',\n  path:'shops',\n  db:DB([{\n    id:0,\n    name:'My Shops',\n    children:[]\n  }])\n})\n\nconst Routes = (opts = {}) =\u003e {\n  return (\n    \u003cRoute path=\"/\" component={AppWrapper}\u003e\n      \u003cIndexRoute component={Home} /\u003e\n      {ProductRoutes}\n      {ShopRoutes}\n    \u003c/Route\u003e\n  )\n}\n\nexport default Routes\n```\n\n## license\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinocarlos%2Ffolder-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinocarlos%2Ffolder-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinocarlos%2Ffolder-ui/lists"}