Skip to content

Commit 57f3042

Browse files
authored
Teach the Atlas3 skills to check out and read the real plugin source (#265)
1 parent 716613e commit 57f3042

2 files changed

Lines changed: 140 additions & 20 deletions

File tree

plugins/devx/skills/testing-atlas3-locally/SKILL.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@ description: Use when running, previewing or verifying Atlas3 / OHDSI ATLAS v3 l
55

66
# Testing Atlas3 locally
77

8-
Atlas3 is a standalone Vue 3 + Vite app (`/home/ph/code/Atlas3`), **not** a
8+
Atlas3 is a standalone Vue 3 + Vite app in its own git repository, **not** a
99
d2e app served through trex. `testing-d2e-ui` and `d2e-ui-preview` are about
1010
building a d2e app and overwriting the resources trex serves on :41100 — they
11-
do not apply here. Plugin authoring lives in **`writing-atlas3-plugins`**.
11+
do not apply here. Plugin authoring lives in **`writing-atlas3-plugins`**,
12+
which also covers checking the repo out.
1213

1314
## Run it
1415

1516
```bash
16-
cd /home/ph/code/Atlas3
17+
# Same checkout writing-atlas3-plugins uses; clone it there if it's missing.
18+
ATLAS3_DIR="${ATLAS3_DIR:-$HOME/code/Atlas3}"
19+
cd "$ATLAS3_DIR"
1720
npm install # first time
1821
BROWSER=none npm run dev # http://localhost:5173 (strictPort)
1922
```

plugins/devx/skills/writing-atlas3-plugins/SKILL.md

Lines changed: 134 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,159 @@
11
---
22
name: writing-atlas3-plugins
3-
description: Use when building, scaffolding or changing an Atlas3 / OHDSI ATLAS v3 plugin — "build an atlas plugin that…", "add a plugin to atlas", a new Atlas panel/tab/FAB/menu entry, or an Atlas plugin that has to match a Figma design. Not for Data2Evidence portal apps.
3+
description: Use when building, scaffolding or changing an Atlas3 / OHDSI ATLAS v3 plugin — "build an atlas plugin that…", "add a plugin to atlas", a new Atlas panel/tab/FAB/menu entry, or an Atlas plugin that has to match a Figma design. Also use when you need an Atlas3 component's real props/events or the host plugin contract: the published package ships no source or types, so this skill covers checking out OHDSI/Atlas3, reading @ohdsi/atlas-ui's actual signatures, and building the UI from the Atlas* component library rather than hand-rolled markup. Not for Data2Evidence portal apps.
44
---
55

66
# Writing Atlas3 plugins
77

88
An Atlas3 plugin is a **single-spa parcel** built in **`system` module format**,
99
dropped into the host's `public/plugins/<id>/` and declared in a JSON manifest.
10-
`/home/ph/code/Atlas3/docs/plugin-development-with-atlas-ui.md` is the reference
11-
for the contract, `PluginProps`, the `Atlas*` component library and theming —
12-
**read it before implementing**. This skill is the operational wrapper: how to
13-
scaffold, name, build, register and verify. Run the app with
14-
**`testing-atlas3-locally`**.
10+
`docs/plugin-development-with-atlas-ui.md` **inside the Atlas3 checkout** is the
11+
reference for the contract, `PluginProps`, the `Atlas*` component library and
12+
theming — **read it before implementing**. This skill is the operational
13+
wrapper: how to check out the source, find the real contracts, scaffold, name,
14+
build, register and verify. Run the app with **`testing-atlas3-locally`**.
15+
16+
**You cannot do this job from `node_modules` alone.** The published
17+
`@ohdsi/atlas3` package sets `"files": ["dist"]` and ships **no `.d.ts` and no
18+
source** — just a built bundle. Every component signature, prop, event and type
19+
below exists *only* in the Atlas3 git repository. Guessing a prop name because
20+
it sounds right is the single most common way these plugins fail. Check the
21+
source out (step 1) and read it.
1522

1623
## Workflow
1724

18-
1. **Design first, if there is one.** A Figma link (or "match this design") →
25+
1. **Check out Atlas3 — always, before anything else.** Clone it if it isn't
26+
already present, then work *inside* it under `plugins-dev/`: the reference
27+
plugin's `@ohdsi/atlas-ui` and `outDir` paths are relative to that location.
28+
29+
```bash
30+
ATLAS3_DIR="${ATLAS3_DIR:-$HOME/code/Atlas3}"
31+
[ -d "$ATLAS3_DIR/.git" ] || git clone git@github.com:OHDSI/Atlas3.git "$ATLAS3_DIR"
32+
git -C "$ATLAS3_DIR" fetch origin --quiet
33+
```
34+
35+
A pre-existing checkout may be stale or on someone's feature branch — check
36+
`git -C "$ATLAS3_DIR" log --oneline -1` and `git status` before trusting it;
37+
`git pull` on `develop` if it is behind. If the SSH remote is unavailable,
38+
fall back to `https://github.com/OHDSI/Atlas3.git`.
39+
2. **Read the real contracts out of that checkout** before writing a component —
40+
see *Finding the exact contract in source* below. For worked examples beyond
41+
the hello-world starter, read the shipped plugins in `OHDSI/trex-notebook`
42+
(see *Reference implementations*).
43+
3. **Design first, if there is one.** A Figma link (or "match this design") →
1944
use **`pulling-figma-mockups`** BEFORE writing any component, then implement
2045
against the `.spec.json` (see *Figma → Atlas tokens* below).
21-
2. **Locate Atlas3.** `/home/ph/code/Atlas3` locally, otherwise clone
22-
`OHDSI/Atlas3`. Work *inside* it, under `plugins-dev/` — the reference
23-
plugin's `@ohdsi/atlas-ui` and `outDir` paths are relative to that location.
24-
3. **Scaffold by copying**, never from scratch:
46+
4. **Scaffold by copying**, never from scratch:
2547
`cp -r plugins-dev/hello-world-plugin plugins-dev/<plugin-id>`, then delete
2648
its `package-lock.json`. You get a complete working parcel: `package.json`,
2749
`vite.config.mjs`, `tsconfig.json`, `tsconfig.node.json`, `src/main.ts`,
2850
`src/App.vue`.
29-
4. **Rename the id consistently** (table below). A mismatch fails silently —
51+
5. **Rename the id consistently** (table below). A mismatch fails silently —
3052
the app boots, the plugin just never appears.
31-
5. **Build the component library once**, from the Atlas3 root:
53+
6. **Build the component library once**, from the Atlas3 root:
3254
`npm run lib:build`. `@ohdsi/atlas-ui`'s `exports` point at the gitignored
3355
`packages/atlas-ui/dist/`, absent in a fresh checkout; without it the plugin
3456
build dies on *Failed to resolve entry for package @ohdsi/atlas-ui*.
35-
6. **Implement.** Leave `main.ts` alone (lifecycles + `buildVuetifyOptions()`);
36-
put your UI in `App.vue` and components beside it.
37-
7. **Build:** `cd plugins-dev/<plugin-id> && npm install && npm run build`
57+
7. **Implement out of `Atlas*` components** (see *Build the UI from the Atlas
58+
component library* — this is the rule, not a preference). Leave `main.ts`
59+
alone (lifecycles + `buildVuetifyOptions()`); put your UI in `App.vue` and
60+
components beside it.
61+
8. **Build:** `cd plugins-dev/<plugin-id> && npm install && npm run build`
3862
`public/plugins/<plugin-id>/index.system.js`.
39-
8. **Register** (below), then verify with **`testing-atlas3-locally`**.
63+
9. **Register** (below), then verify with **`testing-atlas3-locally`**.
64+
65+
## Build the UI from the Atlas component library
66+
67+
**Every piece of UI you render must come from an `Atlas*` component when one
68+
exists for the job.** The point of a plugin is that it is indistinguishable
69+
from native Atlas — an `Atlas*` component already carries the theme, the
70+
spacing scale, the dark-mode palette, the focus/ARIA behaviour and the
71+
Atlas-specific defaults. Hand-rolled markup gets none of that and drifts the
72+
moment the design system moves.
73+
74+
The precedence, highest first:
75+
76+
1. **`Atlas*` component** from `@ohdsi/atlas-ui` — always, if one fits.
77+
`packages/atlas-ui/index.ts` is the list of what exists; check it before
78+
concluding there is nothing.
79+
2. **Raw Vuetify (`v-*`)** — only for a primitive with no `Atlas*` wrapper.
80+
Style it with theme tokens (`--v-theme-*`, `--atlas-*`), never literal
81+
colors or pixel values.
82+
3. **Your own markup** — last resort, for genuinely bespoke layout. Same token
83+
rule applies, and it still sits inside `AtlasPageShell`/`AtlasContainer`.
84+
85+
Never introduce a *third-party* UI kit or icon set into a plugin — no Element
86+
Plus, no Bootstrap, no Tailwind. Vuetify + `@ohdsi/atlas-ui` + `mdi` icons is
87+
the whole toolkit; a second one ships a duplicate CSS reset and visibly breaks
88+
the shell.
89+
90+
If you conclude no `Atlas*` component fits, say which one you looked at and why
91+
it did not, in your reply. That is a design-system gap worth reporting, and it
92+
is the difference between a considered fallback and a silent one.
93+
94+
## Finding the exact contract in source
95+
96+
Read these files in the Atlas3 checkout — do not infer any of it, and do not
97+
reach for a raw Vuetify component when an `Atlas*` wrapper exists.
98+
99+
| What you need | Read (paths relative to the Atlas3 checkout) |
100+
|---|---|
101+
| **Which components exist** — the authoritative inventory | `packages/atlas-ui/index.ts` (every export in one file) |
102+
| **A component's exact props, events, slots, defaults** | `src/components/ui/<Name>.vue` — read its `defineProps`/`defineEmits`; charts live under `src/components/ui/charts/` |
103+
| **Host → plugin contract** (`PluginProps`, `AuthContext`, `PluginMessageBus`) | `src/models/PluginModels.ts` — also the zod schema the manifest is validated against |
104+
| **Theme tokens and the Vuetify options builder** | `src/ui/tokens.ts`, `src/ui/theme.ts` (`buildVuetifyOptions`), generated `src/ui/tokens.css` |
105+
| **Chart data types and option builders** | `src/ui/chart-types.ts`, `src/ui/chart-config.ts` (`CHART_COLORS`, `multiLineChartOptions`, …) |
106+
| **A complete working parcel** | `plugins-dev/hello-world-plugin/` |
107+
| **The narrative guide** | `docs/plugin-development-with-atlas-ui.md` |
108+
109+
Fast ways to answer a concrete question, run from the checkout root:
110+
111+
```bash
112+
# Is there an Atlas component for this, and what is it called?
113+
grep -n 'export { default as Atlas' packages/atlas-ui/index.ts
114+
115+
# What props/events does one actually take?
116+
sed -n '1,80p' src/components/ui/AtlasDataTable.vue
117+
118+
# What non-component values are exported (tokens, builders, types)?
119+
grep -nE '^export (\{|type|const)' packages/atlas-ui/index.ts | grep -v 'default as'
120+
```
121+
122+
The inventory currently spans form controls (`AtlasTextField`, `AtlasSelect`,
123+
`AtlasAutocomplete`, `AtlasCheckbox`, `AtlasRadioGroup`, `AtlasSwitch`), layout
124+
(`AtlasPageShell`, `AtlasContainer`, `AtlasRow`, `AtlasCol`, `AtlasCard`,
125+
`AtlasDivider`, `AtlasSpacer`), feedback (`AtlasAlert`, `AtlasBanner`,
126+
`AtlasSnackbar`, `AtlasDialog`, `AtlasProgressLinear`, `AtlasProgressCircular`,
127+
`AtlasSkeleton`), navigation (`AtlasTabs`/`AtlasTab`, `AtlasMenu`, `AtlasList`/
128+
`AtlasListItem`, `AtlasPagination`), data display (`AtlasDataTable`,
129+
`AtlasChip`, `AtlasBadge`, `AtlasAvatar`, `AtlasTooltip`, `AtlasIcon`) and
130+
charts (`AtlasBarChart`, `AtlasLineChart`, `AtlasPieChart`, `AtlasBoxPlotChart`,
131+
`AtlasTreemapChart`, `AtlasSunburstChart`, `AtlasTrellisChart`,
132+
`AtlasChartExport`). Treat that list as a hint about *where to look*, not as
133+
truth — `packages/atlas-ui/index.ts` in the checkout you just pulled is truth.
134+
135+
## Reference implementations
136+
137+
`OHDSI/trex-notebook` ships the production Atlas3 plugins and is the best
138+
source of worked patterns beyond the hello-world starter. Check it out the same
139+
way (`git clone git@github.com:OHDSI/trex-notebook.git`); in a Data2Evidence
140+
checkout it is already vendored at `plugins/atlas/trex-notebook/`.
141+
142+
Its **UI** plugins — `network`, `notebook-plugin`, `results-viewer`, `sibyl`,
143+
`strategus`, `studies` (each under `plugins/`) — all depend on
144+
`@ohdsi/atlas-ui`, build `formats: ['system']`, and are worth reading for how a
145+
real plugin structures views, state (Pinia) and API calls. The `*-api` siblings
146+
(`hades-api`, `metadata-api`, `network-api`) are backend plugins with no UI —
147+
not templates for this task.
148+
149+
Note they depend on a **published** `"@ohdsi/atlas-ui": "^0.1.0-…"` version,
150+
whereas a plugin developed inside the Atlas3 monorepo uses
151+
`file:../../packages/atlas-ui`. Match whichever tree you are working in.
152+
153+
**Do not use `plugins/ui/apps/vue-mri-ui-lib` (the D2E patient-analytics app)
154+
as a template.** It is a large standalone SAPUI5-era Vue app that predates this
155+
contract: it is not a single-spa parcel, does not use `@ohdsi/atlas-ui`, and
156+
copying it produces a plugin that neither themes nor mounts correctly.
40157

41158
## The id appears in five places — all must agree
42159

0 commit comments

Comments
 (0)