Skip to content

Commit

Permalink
feat: WIP content browser component
Browse files Browse the repository at this point in the history
  • Loading branch information
ninanoleto committed Feb 13, 2025
1 parent 450b5ea commit 2e37e54
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 0 deletions.
34 changes: 34 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,40 @@ module.exports = {
use: ["@svgr/webpack"],
});

// Support Svelte
config.module.rules.push({
test: /\.svelte$/,
use: [
{
loader: "svelte-loader",
options: {
compilerOptions: {
dev: true,
},
emitCss: true,
hotReload: true,
},
},
],
});

// TODO: make the mock work
// Force Storybook to always use the mock instead of the real component ?
config.resolve.alias["./src/pat/contentbrowser/src/App.svelte"] = path.resolve(
__dirname,
"../src/pat/contentbrowser/src/App.mock.js"
);
config.resolve.alias["#pat/contentbrowser/src/App"] = path.resolve(
__dirname,
"../src/pat/contentbrowser/src/App.mock.js"
);
config.resolve.alias["./src/pat/contentbrowser/src/SelectedItem.svelte"] =
path.resolve(__dirname, "../src/pat/contentbrowser/src/App.mock.js");
config.resolve.alias["#pat/contentbrowser/src/App"] = path.resolve(
__dirname,
"../src/pat/contentbrowser/src/SelectedItem.mock.js"
);

return config;
},
};
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@
"sass": "~1.77.8",
"underscore": "1.13.7"
},
"imports": {
"#pat/contentbrowser/src/App": {
"storybook": "./src/pat/contentbrowser/src/App.mock.js",
"default": "./src/pat/contentbrowser/src/App.svelte"
},
"#pat/contentbrowser/src/SelectedItem": {
"storybook": "./src/pat/contentbrowser/src/SelectedItem.mock.js",
"default": "./src/pat/contentbrowser/src/SelectedItem.svelte"
}
},
"scripts": {
"clean": "rimraf docs/_site",
"build:webpack": "NODE_ENV=production webpack --config webpack.config.js",
Expand Down
48 changes: 48 additions & 0 deletions src/pat/contentbrowser/contentbrowser.docs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Meta, Story } from "@storybook/addon-docs";
import { ContentBrowser } from "./contentbrowser.stories.js";

<Meta title="Patterns/ContentBrowser" />

# Contentbrowser

Show a widget to select items in an offcanvas miller-column browser.

## Configuration

```md
| Option | Type | Default | Description |
| :------------------: | :-----: | :-------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: |
| vocabularyUrl | string | null | This is a URL to a JSON-formatted file used to populate the list |
| attributes | array | ['UID', 'Title', 'portal_type', 'path'] | This list is passed to the server during an AJAX request to specify the attributes which should be included on each item. |
| rootPath | string | "/" | Browsing/searching root path. You will not get beneath this path |
| rootUrl | string | | Browsing/searching root url. |
| basePath | string | set to rootPath. | Start browse/search in this path. |
| contextPath | string | | Path of the object, which is currently edited. If this path is given, this object will not be selectable. |
| favorites | array | [] | Array of objects. These are favorites, which can be used to quickly jump to different locations. Objects have the attributes "title" and "path". |
| maximumSelectionSize | integer | -1 | The maximum number of items that can be selected in a multi-select control. If this number is less than 1 selection is not limited. |
| mode | string | "browse" | Toggle between "browse" and "search" |
| width | integer | | Override the width of the selected items field |
| bSize | integer | 10 | Batch size of the items listed in levels |
| maxDepth | integer | | Maximum level depth for "browse" mode |
| separator | string | ',' | Select2 option. String which separates multiple items. |
| upload | boolean | | Allow file and image uploads from within the related items widget. |
| recentlyUsed | boolean | false | Show the recently used items dropdown. |
| recentlyUsedKey | integer | | Storage key for saving the recently used items. This is generated with fieldname and username in the patternoptions. |
| recentlyUsedMaxItems | integer | 20 | Maximum items to keep in recently used list. 0: no restriction. |
| customComponentKeys | dict | {} | Register custom components. Currently only "SelectedItem" implemented |
```

## Examples

### Simple

<br />
<Story name="Content Browser" of={ContentBrowser} />

```html
<input
type="text"
class="pat-contentbrowser"
data-pat-contentbrowser='{"selectableTypes": ["Document"], "vocabularyUrl": "contentbrowser-test.json"}'
/>
```
5 changes: 5 additions & 0 deletions src/pat/contentbrowser/contentbrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import registry from "@patternslib/patternslib/src/core/registry";
import utils from "../../core/utils";
import plone_registry from "@plone/registry";

// TODO: make SB mock work ?
// Subpath imports from package.json (so Storybook can mock them)
import SelectedItem from "#pat/contentbrowser/src/SelectedItem";
import ContentBrowserApp from "#pat/contentbrowser/src/App";

// Contentbrowser pattern

export const parser = new Parser("contentbrowser");
Expand Down
45 changes: 45 additions & 0 deletions src/pat/contentbrowser/contentbrowser.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import $ from "jquery";
import { RenderHTML } from "../../../.storybook/setup.js";
import ContentBrowserComponent from "./contentbrowser.js";

export default {
title: "Patterns/ContentBrowser",
parameters: {
mockData: [
{
url: "/contentbrowser-test.json", // Fake API URL
method: "GET",
status: 200,
response: {
items: [
{
UID: "1234",
Title: "Example Document",
path: "/example-document",
},
{ UID: "5678", Title: "Another Item", path: "/another-item" },
],
},
},
],
},
};

// Basic Contentbrowser
const getContentBrowser = (args) => `
<input
type="text"
class="pat-contentbrowser"
data-pat-contentbrowser='{"vocabularyUrl": "${args.vocabularyUrl}"}'
/>
`;

// TODO:
// Story for this component: error Invalid URL
// Check svelte components mocks ?
export const ContentBrowser = {
render: (args) => RenderHTML(args, getContentBrowser),
args: {
vocabularyUrl: "/contentbrowser-test.json",
},
};
17 changes: 17 additions & 0 deletions src/pat/contentbrowser/src/App.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
console.log("Using App:", import.meta.url);

// TODO:
// How to prevent App.svelte from running ?
// both mock and real App.svelte are running rn
if (typeof window !== "undefined") {
console.log({ aqui: window.ContentBrowserApp });
window.ContentBrowserApp = "alala";
console.log({ aqui: window.ContentBrowserApp });
}

export default function MockContentBrowserApp({ target, props }) {
console.log("MockSelectedItem initialized with", props);
target.innerHTML = `<div style="border: 2px solid blue; padding: 10px;">
Mocked Content Browser App
</div>`;
}
2 changes: 2 additions & 0 deletions src/pat/contentbrowser/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script>
console.log("Using App:", import.meta.url);
import logger from "@patternslib/patternslib/src/core/logging";
import { getContext } from "svelte";
import ContentBrowser from "./ContentBrowser.svelte";
Expand Down
6 changes: 6 additions & 0 deletions src/pat/contentbrowser/src/SelectedItem.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default function MockSelectedItem({ target, props }) {
console.log("MockSelectedItem initialized with", props);
target.innerHTML = `<div style="border: 2px solid blue; padding: 10px;">
Mocked Selected Item
</div>`;
}

0 comments on commit 2e37e54

Please sign in to comment.