splent-feature-team 0.3.2__tar.gz
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.
- splent_feature_team-0.3.2/MANIFEST.in +27 -0
- splent_feature_team-0.3.2/PKG-INFO +5 -0
- splent_feature_team-0.3.2/pyproject.toml +58 -0
- splent_feature_team-0.3.2/setup.cfg +4 -0
- splent_feature_team-0.3.2/src/splent_feature_team.egg-info/PKG-INFO +5 -0
- splent_feature_team-0.3.2/src/splent_feature_team.egg-info/SOURCES.txt +78 -0
- splent_feature_team-0.3.2/src/splent_feature_team.egg-info/dependency_links.txt +1 -0
- splent_feature_team-0.3.2/src/splent_feature_team.egg-info/top_level.txt +1 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/__init__.py +25 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/assets/css/team.css +138 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/assets/dist/splent_feature_team.bundle.js +20 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/assets/dist/splent_feature_team.bundle.js.map +1 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/assets/js/scripts.js +12 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/assets/js/webpack.config.js +14 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/commands.py +21 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/config.py +19 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/forms.py +6 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/hooks.py +23 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/migrations/alembic.ini +36 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/migrations/env.py +9 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/migrations/script.py.mako +24 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/migrations/versions/1bb39441d98d_splent_feature_team.py +46 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/migrations/versions/3f76830b5164_splent_feature_team.py +29 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/migrations/versions/tm0003_roles_m2m.py +101 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/models.py +73 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/repositories.py +38 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/routes.py +203 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/alberto-valenzuela-munoz.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/ana-eva-chacon-luna.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/antonio-german-marquez-trujillo.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/antonio-j-dominguez.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/antonio-jimenez-ortega.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/antonio-manuel-guiterrez-fernandez.webp +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/asmaa-hasan-sbaih.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/cristian-vidal-silva.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/daniel-molina-torres.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/david-benavides.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/david-romero-organvidez.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/esther-rocio-valladolid-ortiz.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/f-j-dominguez-mayo.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/felipe-escalera-gonzalez.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/francisco-sebastian-benitez-ruis-diaz.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/guillermo-ciria-gonzalez.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/isabel-mylonas.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/javier-aponte.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jesennia-cardenas-cobo.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jesus-fernandez-romero.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jesus-moreno-leon.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jorge-garcia.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jorge-rodas-silva.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jose-a-galindo.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jose-a-zamudio.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jose-manuel-sanchez-ruiz.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/jose-miguel-horcas.webp +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/julio-navarro-rodriguez.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/mario-rivas-becerra.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/mariuxi-vinueza-morales.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/megha-bhushan.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/miguel-moreno-martin-palomo.png +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/miguel-olivero.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/noelia-lopez-duran.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/pablo-neira.png +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/pablo-pazo.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/pablo-ramos-berciano.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/rafael-harana-mancilla.png +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/salvador-munoz-hermoso.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/victor-ramirez-de-la-corte.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seed_media/victor-rea-sanchez.jpg +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/seeders.py +621 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/services.py +17 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/signals.py +19 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/templates/team/admin/form.html +81 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/templates/team/admin/list.html +88 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/templates/team/admin/roles.html +82 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/templates/team/detail.html +44 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/templates/team/index.html +10 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/templates/team/list.html +33 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/translations/es/LC_MESSAGES/messages.mo +0 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/translations/es/LC_MESSAGES/messages.po +44 -0
- splent_feature_team-0.3.2/src/splent_io/splent_feature_team/translations/messages.pot +43 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Frontend assets: the whole tree, not only the compiled bundles.
|
|
2
|
+
#
|
|
3
|
+
# A feature that registers a plain stylesheet with register_asset("css", …)
|
|
4
|
+
# serves it straight from assets/css, and a vendored library lives under
|
|
5
|
+
# assets/vendor. Shipping assets/dist alone put no stylesheet at all in the
|
|
6
|
+
# built package, so every production image came up without its theme, its
|
|
7
|
+
# skin and its editor, while development looked fine because that path
|
|
8
|
+
# installs the checkout in place and reads the files off disk.
|
|
9
|
+
recursive-include src/splent_io/splent_feature_team/assets *.css *.js *.map *.json
|
|
10
|
+
recursive-include src/splent_io/splent_feature_team/assets *.svg *.png *.jpg *.jpeg *.gif *.webp *.ico
|
|
11
|
+
recursive-include src/splent_io/splent_feature_team/assets *.woff *.woff2 *.ttf *.eot
|
|
12
|
+
|
|
13
|
+
# Build inputs, never shipped.
|
|
14
|
+
prune src/splent_io/splent_feature_team/assets/node_modules
|
|
15
|
+
|
|
16
|
+
# Seed photos, imported through the media feature on db:seed.
|
|
17
|
+
recursive-include src/splent_io/splent_feature_team/seed_media *.jpg *.jpeg *.png *.webp
|
|
18
|
+
|
|
19
|
+
# Jinja templates (feature views + hook fragments)
|
|
20
|
+
recursive-include src/splent_io/splent_feature_team/templates *.html
|
|
21
|
+
|
|
22
|
+
# Alembic migration config and scripts
|
|
23
|
+
recursive-include src/splent_io/splent_feature_team/migrations *.py *.ini *.mako
|
|
24
|
+
|
|
25
|
+
# Translations. The .mo is what gettext reads at runtime; the .po
|
|
26
|
+
# travels with it so the next translator has something to edit.
|
|
27
|
+
recursive-include src/splent_io/splent_feature_team/translations *.mo *.po *.pot
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=80.3.1", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "splent_feature_team"
|
|
7
|
+
version = "0.3.2"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.13"
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[tool.setuptools]
|
|
16
|
+
package-dir = { "" = "src" }
|
|
17
|
+
include-package-data = true
|
|
18
|
+
|
|
19
|
+
[tool.setuptools.packages.find]
|
|
20
|
+
where = ["src"]
|
|
21
|
+
exclude = ["*.tests", "*.tests.*"]
|
|
22
|
+
|
|
23
|
+
[tool.splent]
|
|
24
|
+
cli_version = "1.11.0"
|
|
25
|
+
|
|
26
|
+
# ── Feature Contract (auto-generated) ────────────────────────────────────────
|
|
27
|
+
# Do not edit manually — re-run `splent feature:contract --write` to refresh.
|
|
28
|
+
# Preserved across refreshes: description, category, tags, env,
|
|
29
|
+
# requires.features_manual (dependencies invisible to static analysis)
|
|
30
|
+
# and provides.routes_manual (routes built from configuration at
|
|
31
|
+
# registration time, which have no literal path to find in source).
|
|
32
|
+
[tool.splent.contract]
|
|
33
|
+
description = "People directory (organisers, faculty, speakers) with public list/detail and admin CRUD"
|
|
34
|
+
archetype = "full"
|
|
35
|
+
|
|
36
|
+
[tool.splent.contract.provides]
|
|
37
|
+
routes = ["/admin/team", "/admin/team/<int:member_id>/delete", "/admin/team/<int:member_id>/edit", "/admin/team/new", "/admin/team/roles", "/admin/team/roles/<int:role_id>/delete", "/admin/team/roles/<int:role_id>/edit", "/team", "/team/<slug>"]
|
|
38
|
+
blueprints = []
|
|
39
|
+
models = ["Role", "TeamMember"]
|
|
40
|
+
commands = ["hello"]
|
|
41
|
+
hooks = ["layout.authenticated_sidebar"]
|
|
42
|
+
services = ["TeamService"]
|
|
43
|
+
signals = []
|
|
44
|
+
translations = ["es"]
|
|
45
|
+
docker = []
|
|
46
|
+
|
|
47
|
+
[tool.splent.contract.requires]
|
|
48
|
+
features = ["media"]
|
|
49
|
+
features_manual = ["media"]
|
|
50
|
+
env_vars = []
|
|
51
|
+
signals = []
|
|
52
|
+
|
|
53
|
+
[tool.splent.contract.extensible]
|
|
54
|
+
services = ["TeamService"]
|
|
55
|
+
templates = ["team/admin/form.html", "team/admin/list.html", "team/admin/roles.html", "team/detail.html", "team/index.html", "team/list.html"]
|
|
56
|
+
models = ["Role", "TeamMember"]
|
|
57
|
+
hooks = ["layout.authenticated_sidebar"]
|
|
58
|
+
routes = false
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
MANIFEST.in
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/splent_feature_team.egg-info/PKG-INFO
|
|
4
|
+
src/splent_feature_team.egg-info/SOURCES.txt
|
|
5
|
+
src/splent_feature_team.egg-info/dependency_links.txt
|
|
6
|
+
src/splent_feature_team.egg-info/top_level.txt
|
|
7
|
+
src/splent_io/splent_feature_team/__init__.py
|
|
8
|
+
src/splent_io/splent_feature_team/commands.py
|
|
9
|
+
src/splent_io/splent_feature_team/config.py
|
|
10
|
+
src/splent_io/splent_feature_team/forms.py
|
|
11
|
+
src/splent_io/splent_feature_team/hooks.py
|
|
12
|
+
src/splent_io/splent_feature_team/models.py
|
|
13
|
+
src/splent_io/splent_feature_team/repositories.py
|
|
14
|
+
src/splent_io/splent_feature_team/routes.py
|
|
15
|
+
src/splent_io/splent_feature_team/seeders.py
|
|
16
|
+
src/splent_io/splent_feature_team/services.py
|
|
17
|
+
src/splent_io/splent_feature_team/signals.py
|
|
18
|
+
src/splent_io/splent_feature_team/assets/css/team.css
|
|
19
|
+
src/splent_io/splent_feature_team/assets/dist/splent_feature_team.bundle.js
|
|
20
|
+
src/splent_io/splent_feature_team/assets/dist/splent_feature_team.bundle.js.map
|
|
21
|
+
src/splent_io/splent_feature_team/assets/js/scripts.js
|
|
22
|
+
src/splent_io/splent_feature_team/assets/js/webpack.config.js
|
|
23
|
+
src/splent_io/splent_feature_team/migrations/alembic.ini
|
|
24
|
+
src/splent_io/splent_feature_team/migrations/env.py
|
|
25
|
+
src/splent_io/splent_feature_team/migrations/script.py.mako
|
|
26
|
+
src/splent_io/splent_feature_team/migrations/versions/1bb39441d98d_splent_feature_team.py
|
|
27
|
+
src/splent_io/splent_feature_team/migrations/versions/3f76830b5164_splent_feature_team.py
|
|
28
|
+
src/splent_io/splent_feature_team/migrations/versions/tm0003_roles_m2m.py
|
|
29
|
+
src/splent_io/splent_feature_team/seed_media/alberto-valenzuela-munoz.jpg
|
|
30
|
+
src/splent_io/splent_feature_team/seed_media/ana-eva-chacon-luna.jpg
|
|
31
|
+
src/splent_io/splent_feature_team/seed_media/antonio-german-marquez-trujillo.jpg
|
|
32
|
+
src/splent_io/splent_feature_team/seed_media/antonio-j-dominguez.jpg
|
|
33
|
+
src/splent_io/splent_feature_team/seed_media/antonio-jimenez-ortega.jpg
|
|
34
|
+
src/splent_io/splent_feature_team/seed_media/antonio-manuel-guiterrez-fernandez.webp
|
|
35
|
+
src/splent_io/splent_feature_team/seed_media/asmaa-hasan-sbaih.jpg
|
|
36
|
+
src/splent_io/splent_feature_team/seed_media/cristian-vidal-silva.jpg
|
|
37
|
+
src/splent_io/splent_feature_team/seed_media/daniel-molina-torres.jpg
|
|
38
|
+
src/splent_io/splent_feature_team/seed_media/david-benavides.jpg
|
|
39
|
+
src/splent_io/splent_feature_team/seed_media/david-romero-organvidez.jpg
|
|
40
|
+
src/splent_io/splent_feature_team/seed_media/esther-rocio-valladolid-ortiz.jpg
|
|
41
|
+
src/splent_io/splent_feature_team/seed_media/f-j-dominguez-mayo.jpg
|
|
42
|
+
src/splent_io/splent_feature_team/seed_media/felipe-escalera-gonzalez.jpg
|
|
43
|
+
src/splent_io/splent_feature_team/seed_media/francisco-sebastian-benitez-ruis-diaz.jpg
|
|
44
|
+
src/splent_io/splent_feature_team/seed_media/guillermo-ciria-gonzalez.jpg
|
|
45
|
+
src/splent_io/splent_feature_team/seed_media/isabel-mylonas.jpg
|
|
46
|
+
src/splent_io/splent_feature_team/seed_media/javier-aponte.jpg
|
|
47
|
+
src/splent_io/splent_feature_team/seed_media/jesennia-cardenas-cobo.jpg
|
|
48
|
+
src/splent_io/splent_feature_team/seed_media/jesus-fernandez-romero.jpg
|
|
49
|
+
src/splent_io/splent_feature_team/seed_media/jesus-moreno-leon.jpg
|
|
50
|
+
src/splent_io/splent_feature_team/seed_media/jorge-garcia.jpg
|
|
51
|
+
src/splent_io/splent_feature_team/seed_media/jorge-rodas-silva.jpg
|
|
52
|
+
src/splent_io/splent_feature_team/seed_media/jose-a-galindo.jpg
|
|
53
|
+
src/splent_io/splent_feature_team/seed_media/jose-a-zamudio.jpg
|
|
54
|
+
src/splent_io/splent_feature_team/seed_media/jose-manuel-sanchez-ruiz.jpg
|
|
55
|
+
src/splent_io/splent_feature_team/seed_media/jose-miguel-horcas.webp
|
|
56
|
+
src/splent_io/splent_feature_team/seed_media/julio-navarro-rodriguez.jpg
|
|
57
|
+
src/splent_io/splent_feature_team/seed_media/mario-rivas-becerra.jpg
|
|
58
|
+
src/splent_io/splent_feature_team/seed_media/mariuxi-vinueza-morales.jpg
|
|
59
|
+
src/splent_io/splent_feature_team/seed_media/megha-bhushan.jpg
|
|
60
|
+
src/splent_io/splent_feature_team/seed_media/miguel-moreno-martin-palomo.png
|
|
61
|
+
src/splent_io/splent_feature_team/seed_media/miguel-olivero.jpg
|
|
62
|
+
src/splent_io/splent_feature_team/seed_media/noelia-lopez-duran.jpg
|
|
63
|
+
src/splent_io/splent_feature_team/seed_media/pablo-neira.png
|
|
64
|
+
src/splent_io/splent_feature_team/seed_media/pablo-pazo.jpg
|
|
65
|
+
src/splent_io/splent_feature_team/seed_media/pablo-ramos-berciano.jpg
|
|
66
|
+
src/splent_io/splent_feature_team/seed_media/rafael-harana-mancilla.png
|
|
67
|
+
src/splent_io/splent_feature_team/seed_media/salvador-munoz-hermoso.jpg
|
|
68
|
+
src/splent_io/splent_feature_team/seed_media/victor-ramirez-de-la-corte.jpg
|
|
69
|
+
src/splent_io/splent_feature_team/seed_media/victor-rea-sanchez.jpg
|
|
70
|
+
src/splent_io/splent_feature_team/templates/team/detail.html
|
|
71
|
+
src/splent_io/splent_feature_team/templates/team/index.html
|
|
72
|
+
src/splent_io/splent_feature_team/templates/team/list.html
|
|
73
|
+
src/splent_io/splent_feature_team/templates/team/admin/form.html
|
|
74
|
+
src/splent_io/splent_feature_team/templates/team/admin/list.html
|
|
75
|
+
src/splent_io/splent_feature_team/templates/team/admin/roles.html
|
|
76
|
+
src/splent_io/splent_feature_team/translations/messages.pot
|
|
77
|
+
src/splent_io/splent_feature_team/translations/es/LC_MESSAGES/messages.mo
|
|
78
|
+
src/splent_io/splent_feature_team/translations/es/LC_MESSAGES/messages.po
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
splent_io
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from splent_framework.blueprints.base_blueprint import create_blueprint
|
|
2
|
+
from splent_framework.nav.nav_registry import register_nav_item
|
|
3
|
+
from splent_framework.services.service_locator import register_service
|
|
4
|
+
|
|
5
|
+
from splent_io.splent_feature_team.services import TeamService
|
|
6
|
+
|
|
7
|
+
team_bp = create_blueprint(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def init_feature(app):
|
|
11
|
+
from splent_framework.assets.asset_registry import register_asset
|
|
12
|
+
|
|
13
|
+
# Team is managed through its OWN custom admin screens (see routes.py and
|
|
14
|
+
# hooks.py) — the WordPress-plugin pattern — instead of the generic admin
|
|
15
|
+
# resource, so it does not call register_admin_resource.
|
|
16
|
+
register_service(app, "TeamService", TeamService)
|
|
17
|
+
register_nav_item(key="team", label="Team", href="/team", order=40)
|
|
18
|
+
# Public team-member detail stylesheet (token-driven; styled by the skin).
|
|
19
|
+
register_asset(
|
|
20
|
+
"css", "team.assets", order=100, subfolder="css", filename="team.css"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def inject_context_vars(app):
|
|
25
|
+
return {}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/* ══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
splent_feature_team — public team-member detail sheet.
|
|
3
|
+
Token-driven: every colour/radius comes from the theme's --brand-* custom
|
|
4
|
+
properties, so a skin restyles it for free. Loaded via register_asset on top
|
|
5
|
+
of the theme's public.css. No inline styles, no CDN.
|
|
6
|
+
══════════════════════════════════════════════════════════════════════════ */
|
|
7
|
+
|
|
8
|
+
.member-detail {
|
|
9
|
+
max-width: 72ch;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.member-detail__photo {
|
|
13
|
+
width: 160px;
|
|
14
|
+
height: 160px;
|
|
15
|
+
border-radius: 50%;
|
|
16
|
+
object-fit: cover;
|
|
17
|
+
margin-bottom: 1rem;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.member-roles {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-wrap: wrap;
|
|
23
|
+
gap: .35rem;
|
|
24
|
+
margin-bottom: 1rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.member-detail .section-title {
|
|
28
|
+
margin-top: 1.5rem;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.member-links {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-wrap: wrap;
|
|
34
|
+
gap: .5rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* ── Email contact row: text label / small mail icon, no emoji ─────────────── */
|
|
38
|
+
.member-contact {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: .5rem;
|
|
42
|
+
margin-top: 1rem;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.member-contact__icon {
|
|
46
|
+
flex: none;
|
|
47
|
+
width: 1rem;
|
|
48
|
+
height: 1rem;
|
|
49
|
+
color: var(--brand-primary, #2563eb);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.member-contact__label {
|
|
53
|
+
font-size: .72rem;
|
|
54
|
+
font-weight: 700;
|
|
55
|
+
letter-spacing: .04em;
|
|
56
|
+
text-transform: uppercase;
|
|
57
|
+
color: var(--brand-muted, #6b7280);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.member-detail__back {
|
|
61
|
+
display: inline-block;
|
|
62
|
+
margin-top: 2rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* ── Public team grid: photo-cover cards with a gradient + white text ────────── */
|
|
66
|
+
.member-grid {
|
|
67
|
+
display: grid;
|
|
68
|
+
grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
|
|
69
|
+
gap: 1.25rem;
|
|
70
|
+
margin-bottom: 2.75rem;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.member-card {
|
|
74
|
+
position: relative;
|
|
75
|
+
display: block;
|
|
76
|
+
aspect-ratio: 3 / 4;
|
|
77
|
+
border-radius: var(--brand-radius, 8px);
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
text-decoration: none;
|
|
80
|
+
background: var(--brand-surface, #f1f1f3);
|
|
81
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
|
|
82
|
+
transition: transform .2s ease, box-shadow .2s ease;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.member-card:hover {
|
|
86
|
+
transform: translateY(-4px);
|
|
87
|
+
box-shadow: 0 14px 30px rgba(0, 0, 0, .2);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.member-card__photo {
|
|
91
|
+
position: absolute;
|
|
92
|
+
inset: 0;
|
|
93
|
+
width: 100%;
|
|
94
|
+
height: 100%;
|
|
95
|
+
object-fit: cover;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.member-card__placeholder {
|
|
99
|
+
position: absolute;
|
|
100
|
+
inset: 0;
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
justify-content: center;
|
|
104
|
+
font-family: var(--brand-font-display, var(--brand-font-heading, inherit));
|
|
105
|
+
font-size: 3.5rem;
|
|
106
|
+
color: var(--brand-muted, #9aa3af);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.member-card__overlay {
|
|
110
|
+
position: absolute;
|
|
111
|
+
inset: 0;
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
justify-content: flex-end;
|
|
115
|
+
padding: 1.1rem 1.2rem;
|
|
116
|
+
background: linear-gradient(
|
|
117
|
+
180deg,
|
|
118
|
+
transparent 42%,
|
|
119
|
+
rgba(0, 0, 0, .45) 68%,
|
|
120
|
+
rgba(0, 0, 0, .88) 100%
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Scoped under .member-card so a skin's generic h3 colour can't override white. */
|
|
125
|
+
.member-card .member-card__name {
|
|
126
|
+
margin: 0;
|
|
127
|
+
color: #ffffff;
|
|
128
|
+
font-size: 1.15rem;
|
|
129
|
+
line-height: 1.2;
|
|
130
|
+
text-shadow: 0 1px 8px rgba(0, 0, 0, .55);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.member-card .member-card__role {
|
|
134
|
+
margin: .2rem 0 0;
|
|
135
|
+
color: rgba(255, 255, 255, .85);
|
|
136
|
+
font-size: .85rem;
|
|
137
|
+
text-shadow: 0 1px 6px rgba(0, 0, 0, .55);
|
|
138
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/******/ (() => { // webpackBootstrap
|
|
2
|
+
/*!*************************************************************************************!*\
|
|
3
|
+
!*** ../splent_feature_team/src/splent_io/splent_feature_team/assets/js/scripts.js ***!
|
|
4
|
+
\*************************************************************************************/
|
|
5
|
+
// Entry point for splent_feature_team frontend assets.
|
|
6
|
+
// Add your JavaScript here. Webpack compiles this into assets/dist/splent_feature_team.bundle.js
|
|
7
|
+
//
|
|
8
|
+
// To load the compiled bundle in the product layout, register it in hooks.py:
|
|
9
|
+
//
|
|
10
|
+
// from splent_framework.hooks.template_hooks import register_template_hook
|
|
11
|
+
// from flask import url_for
|
|
12
|
+
//
|
|
13
|
+
// def team_scripts():
|
|
14
|
+
// return '<script src="' + url_for("team.assets", subfolder="dist", filename="splent_feature_team.bundle.js") + '"></script>'
|
|
15
|
+
//
|
|
16
|
+
// register_template_hook("layout.scripts", team_scripts)
|
|
17
|
+
|
|
18
|
+
/******/ })()
|
|
19
|
+
;
|
|
20
|
+
//# sourceMappingURL=splent_feature_team.bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"splent_feature_team.bundle.js","mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack://diversolab_app/../splent_feature_team/src/splent_io/splent_feature_team/assets/js/scripts.js"],"sourcesContent":["// Entry point for splent_feature_team frontend assets.\n// Add your JavaScript here. Webpack compiles this into assets/dist/splent_feature_team.bundle.js\n//\n// To load the compiled bundle in the product layout, register it in hooks.py:\n//\n// from splent_framework.hooks.template_hooks import register_template_hook\n// from flask import url_for\n//\n// def team_scripts():\n// return '<script src=\"' + url_for(\"team.assets\", subfolder=\"dist\", filename=\"splent_feature_team.bundle.js\") + '\"></script>'\n//\n// register_template_hook(\"layout.scripts\", team_scripts)\n"],"names":[],"sourceRoot":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Entry point for splent_feature_team frontend assets.
|
|
2
|
+
// Add your JavaScript here. Webpack compiles this into assets/dist/splent_feature_team.bundle.js
|
|
3
|
+
//
|
|
4
|
+
// To load the compiled bundle in the product layout, register it in hooks.py:
|
|
5
|
+
//
|
|
6
|
+
// from splent_framework.hooks.template_hooks import register_template_hook
|
|
7
|
+
// from flask import url_for
|
|
8
|
+
//
|
|
9
|
+
// def team_scripts():
|
|
10
|
+
// return '<script src="' + url_for("team.assets", subfolder="dist", filename="splent_feature_team.bundle.js") + '"></script>'
|
|
11
|
+
//
|
|
12
|
+
// register_template_hook("layout.scripts", team_scripts)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
entry: path.resolve(__dirname, './scripts.js'),
|
|
5
|
+
output: {
|
|
6
|
+
filename: 'splent_feature_team.bundle.js',
|
|
7
|
+
path: path.resolve(__dirname, '../dist'),
|
|
8
|
+
},
|
|
9
|
+
resolve: {
|
|
10
|
+
fallback: {
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
mode: 'development',
|
|
14
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI commands contributed by splent_feature_team.
|
|
3
|
+
|
|
4
|
+
These commands are auto-discovered by the framework and exposed in the
|
|
5
|
+
SPLENT CLI under the ``feature:team`` group.
|
|
6
|
+
|
|
7
|
+
Usage::
|
|
8
|
+
|
|
9
|
+
splent feature:team hello
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@click.command("hello")
|
|
16
|
+
def hello():
|
|
17
|
+
"""Example command — replace with your own."""
|
|
18
|
+
click.echo(" Hello from splent_feature_team!")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
cli_commands = [hello]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
team feature configuration.
|
|
3
|
+
|
|
4
|
+
Injects environment variables into Flask app.config.
|
|
5
|
+
Add your feature's env vars here so the framework can track them.
|
|
6
|
+
|
|
7
|
+
To regenerate from source code: splent feature:inject-config splent_feature_team
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os # noqa: F401 — used when adding env vars below
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def inject_config(app):
|
|
14
|
+
app.config.update(
|
|
15
|
+
{
|
|
16
|
+
# Add your feature's env vars here, e.g.:
|
|
17
|
+
# "MY_VAR": os.getenv("MY_VAR", "default_value"),
|
|
18
|
+
}
|
|
19
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from flask import request, url_for
|
|
2
|
+
|
|
3
|
+
from splent_framework.hooks.template_hooks import register_template_hook
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def team_admin_link():
|
|
7
|
+
"""Sidebar entry for the Team management screen (the WP-plugin pattern)."""
|
|
8
|
+
active = (
|
|
9
|
+
"active"
|
|
10
|
+
if request.endpoint and request.endpoint.startswith("team.admin")
|
|
11
|
+
else ""
|
|
12
|
+
)
|
|
13
|
+
return (
|
|
14
|
+
f'<li class="sidebar-item {active}">'
|
|
15
|
+
f'<a class="sidebar-link" href="{url_for("team.admin_index")}">'
|
|
16
|
+
'<i class="align-middle" data-feather="users"></i> '
|
|
17
|
+
'<span class="align-middle">Team</span>'
|
|
18
|
+
"</a>"
|
|
19
|
+
"</li>"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
register_template_hook("layout.authenticated_sidebar", team_admin_link)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[alembic]
|
|
2
|
+
script_location = migrations
|
|
3
|
+
|
|
4
|
+
[loggers]
|
|
5
|
+
keys = root,sqlalchemy,alembic
|
|
6
|
+
|
|
7
|
+
[handlers]
|
|
8
|
+
keys = console
|
|
9
|
+
|
|
10
|
+
[formatters]
|
|
11
|
+
keys = generic
|
|
12
|
+
|
|
13
|
+
[logger_root]
|
|
14
|
+
level = WARN
|
|
15
|
+
handlers = console
|
|
16
|
+
qualname =
|
|
17
|
+
|
|
18
|
+
[logger_sqlalchemy]
|
|
19
|
+
level = WARN
|
|
20
|
+
handlers =
|
|
21
|
+
qualname = sqlalchemy.engine
|
|
22
|
+
|
|
23
|
+
[logger_alembic]
|
|
24
|
+
level = INFO
|
|
25
|
+
handlers =
|
|
26
|
+
qualname = alembic
|
|
27
|
+
|
|
28
|
+
[handler_console]
|
|
29
|
+
class = StreamHandler
|
|
30
|
+
args = (sys.stderr,)
|
|
31
|
+
level = NOTSET
|
|
32
|
+
formatter = generic
|
|
33
|
+
|
|
34
|
+
[formatter_generic]
|
|
35
|
+
format = %(levelname)-5.5s [%(name)s] %(message)s
|
|
36
|
+
datefmt = %H:%M:%S
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Alembic migration environment for splent_feature_team."""
|
|
2
|
+
|
|
3
|
+
from splent_io.splent_feature_team import models # noqa
|
|
4
|
+
from splent_framework.migrations.feature_env import run_feature_migrations
|
|
5
|
+
|
|
6
|
+
FEATURE_NAME = "splent_feature_team"
|
|
7
|
+
FEATURE_TABLES = set()
|
|
8
|
+
|
|
9
|
+
run_feature_migrations(FEATURE_NAME, FEATURE_TABLES)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""${message}
|
|
2
|
+
|
|
3
|
+
Revision ID: ${up_revision}
|
|
4
|
+
Revises: ${down_revision | comma,n}
|
|
5
|
+
Create Date: ${create_date}
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
from alembic import op
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
${imports if imports else ""}
|
|
11
|
+
|
|
12
|
+
# revision identifiers, used by Alembic.
|
|
13
|
+
revision = ${repr(up_revision)}
|
|
14
|
+
down_revision = ${repr(down_revision)}
|
|
15
|
+
branch_labels = ${repr(branch_labels)}
|
|
16
|
+
depends_on = ${repr(depends_on)}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def upgrade():
|
|
20
|
+
${upgrades if upgrades else "pass"}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def downgrade():
|
|
24
|
+
${downgrades if downgrades else "pass"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""splent_feature_team
|
|
2
|
+
|
|
3
|
+
Revision ID: 1bb39441d98d
|
|
4
|
+
Revises:
|
|
5
|
+
Create Date: 2026-06-27 20:03:41.933507
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "1bb39441d98d"
|
|
15
|
+
down_revision = None
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
op.create_table(
|
|
23
|
+
"team_member",
|
|
24
|
+
sa.Column("id", sa.Integer(), nullable=False),
|
|
25
|
+
sa.Column("name", sa.String(length=255), nullable=False),
|
|
26
|
+
sa.Column("slug", sa.String(length=255), nullable=False),
|
|
27
|
+
sa.Column("role", sa.String(length=255), nullable=True),
|
|
28
|
+
sa.Column("affiliation", sa.String(length=255), nullable=True),
|
|
29
|
+
sa.Column("group", sa.String(length=128), nullable=True),
|
|
30
|
+
sa.Column("bio", sa.Text(), nullable=True),
|
|
31
|
+
sa.Column("photo", sa.String(length=512), nullable=True),
|
|
32
|
+
sa.Column("email", sa.String(length=255), nullable=True),
|
|
33
|
+
sa.Column("link", sa.String(length=512), nullable=True),
|
|
34
|
+
sa.Column("order", sa.Integer(), nullable=True),
|
|
35
|
+
sa.Column("published", sa.Boolean(), nullable=True),
|
|
36
|
+
sa.PrimaryKeyConstraint("id"),
|
|
37
|
+
)
|
|
38
|
+
op.create_index(op.f("ix_team_member_slug"), "team_member", ["slug"], unique=True)
|
|
39
|
+
# ### end Alembic commands ###
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def downgrade():
|
|
43
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
44
|
+
op.drop_index(op.f("ix_team_member_slug"), table_name="team_member")
|
|
45
|
+
op.drop_table("team_member")
|
|
46
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""splent_feature_team
|
|
2
|
+
|
|
3
|
+
Revision ID: 3f76830b5164
|
|
4
|
+
Revises: 1bb39441d98d
|
|
5
|
+
Create Date: 2026-06-27 23:28:16.486569
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "3f76830b5164"
|
|
15
|
+
down_revision = "1bb39441d98d"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
op.add_column("team_member", sa.Column("links", sa.JSON(), nullable=True))
|
|
23
|
+
# ### end Alembic commands ###
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def downgrade():
|
|
27
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
28
|
+
op.drop_column("team_member", "links")
|
|
29
|
+
# ### end Alembic commands ###
|