Commit cedc3336 authored by François Ferry's avatar François Ferry
Browse files

feat(react): add a react composant in a CW view.

related: #5
parent 363f1ada70c6
Pipeline #34488 passed with stage
in 1 minute and 13 seconds
cubicweb_tuto.egg-info
.tox
node_modules
cubicweb_tuto/data/map.js
......@@ -9,3 +9,6 @@ include *.ini
prune debian
exclude cubicweb-tuto.spec
exclude .gitlab-ci.yml
include *.js
include *.json
recursive-include appjs *.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import {
ComposableMap,
Geographies,
Geography,
Marker,
Point
} from "react-simple-maps";
const geoUrl = "https://raw.githubusercontent.com/zcreativelabs/react-simple-maps/master/topojson-maps/world-110m.json";
declare const data: {
name: string,
latitude: number,
longitude: number,
}
const MapChart = () => {
return (
<ComposableMap>
<Geographies geography={geoUrl}>
{({ geographies }) =>
geographies
.map(geo => (
<Geography
key={geo.rsmKey}
geography={geo}
fill="#EAEAEC"
stroke="#D6D6DA"
/>
))
}
</Geographies>
<Marker coordinates={[data.longitude, data.latitude] as Point}>
<g
fill="none"
stroke="#FF5533"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
transform="translate(-12, -24)"
>
<circle cx="12" cy="10" r="3" />
<path d="M12 21.7C17.3 17 20 13 20 10a8 8 0 1 0-16 0c0 3 2.7 6.9 8 11.7z" />
</g>
<text
textAnchor="middle"
y={10}
style={{ fontFamily: "system-ui", fill: "#5D5A6D" }}
>
{data.name}
</text>
</Marker>
</ComposableMap>
);
};
function App() {
return <MapChart/>
}
const root = document.getElementById("awesome-map");
ReactDOM.render(<App/>, root);
......@@ -17,14 +17,59 @@
"""cubicweb-tuto views/forms/actions/components for web ui"""
from cubicweb.predicates import is_instance
from cubicweb.utils import json_dumps
from cubicweb.web.views.primary import PrimaryView
class MuseumPrimaryView(PrimaryView):
__select__ = is_instance("Museum")
def render_entity(self, entity):
self.render_entity_toolbox(entity)
self.render_entity_title(entity)
# entity's attributes and relations, excluding meta data
# if the entity isn't meta itself
if self.is_primary():
boxes = self._prepare_side_boxes(entity)
else:
boxes = None
if boxes or hasattr(self, "render_side_related"):
self.w('<table width="100%"><tr><td style="width: 75%">')
self.w('<div class="mainInfo">')
self.content_navigation_components("navcontenttop")
self.render_entity_attributes(entity)
if self.main_related_section:
self.render_entity_relations(entity)
self.render_map(entity)
self.content_navigation_components("navcontentbottom")
self.w("</div>")
# side boxes
if boxes or hasattr(self, "render_side_related"):
self.w("</td><td>")
self.w('<div class="primaryRight">')
self.render_side_boxes(boxes)
self.w("</div>")
self.w("</td></tr></table>")
def render_entity_title(self, entity):
"""Renders the entity title, by default using entity's
:meth:`dc_title()` method.
"""
self.w(f"<h1>{entity.title_with_city}</h1>")
def render_map(self, entity):
"""Renders a map displaying where the museum is."""
if not (entity.latitude and entity.longitude):
return
js_file = f"{self._cw.vreg.config.datadir_url}map.js"
data = json_dumps(entity)
self.w('<div id="awesome-map"></div>')
self.w(
f"""
<script type="text/javascript">
const data = {data};
</script>
<script src={js_file}></script>
"""
)
This diff is collapsed.
{
"name": "cubicweb_tuto",
"version": "1.0.0",
"description": "Summary ------- A cube for new CW tutorial",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"watch": "webpack --watch --mode=development"
},
"author": "Logilab",
"license": "GPL-2.0-or-later",
"dependencies": {
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-simple-maps": "^1.0.3",
"prop-types": "^15.7.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-simple-maps": "^2.3.0",
"ts-loader": "^8.0.14",
"typescript": "^4.1.3",
"webpack": "^5.18.0",
"webpack-cli": "^4.4.0"
}
}
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"jsx": "react",
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
/* Module Resolution Options */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
}
}
const path = require("path");
module.exports = {
entry: {
"map.js": "./appjs/geomap.tsx",
},
output: {
filename: "[name]",
path: path.resolve(__dirname, "./cubicweb_tuto/data/")
},
resolve: {
extensions: [".tsx", ".ts", ".jsx", ".js"]
},
module: {
rules: [
{
test: [/\.tsx?$/],
exclude: /node_modules/,
use: ["ts-loader"]
}
]
},
plugins: []
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment