Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
cdb8642
docs(widgets): add an automatic trame repository fetcher for the tram…
UlysseDurand Jun 26, 2026
eba0a62
docs(widgets): remove jinja2 dependency
UlysseDurand Jun 26, 2026
da80d61
docs(widgets): put github access token in the github workflow
UlysseDurand Jun 26, 2026
46449ab
docs(widgets): schedule website build daily at midnight to fetch new …
UlysseDurand Jun 26, 2026
951aa7b
docs(widgets): add a search bar and multiple tags filtering
UlysseDurand Jun 29, 2026
d22651d
docs(widgets): add repositories whitelist
UlysseDurand Jun 30, 2026
12fb7ac
docs(widgets): add warning to non Kitware-owned repositories
UlysseDurand Jun 30, 2026
0b2c8e6
docs(widgets): sort repositories by name
UlysseDurand Jun 30, 2026
a1b0efd
docs(widgets): add vue2 and vue3 tag topics
UlysseDurand Jun 30, 2026
75b98c7
docs(widgets): add sorting, add github stats
UlysseDurand Jul 1, 2026
5ab575d
docs(widgets): separate widgets page of applications page
UlysseDurand Jul 10, 2026
cd66f1f
Merge branch 'Kitware:master' into trame-registry
UlysseDurand Jul 10, 2026
57a1cc7
docs(widgets): replace list with pills and send to github topic page …
UlysseDurand Jul 10, 2026
93c476d
Merge branch 'trame-registry' of github.com:UlysseDurand/trame into t…
UlysseDurand Jul 10, 2026
cf66815
docs(catalog): make a vue component for repositories list
UlysseDurand Jul 13, 2026
b0cdf55
Merge branch 'Kitware:master' into trame-registry
UlysseDurand Jul 13, 2026
0139ad6
docs(ci): add install python dependencies step
UlysseDurand Jul 13, 2026
84f9961
docs(catalog): add wildcard matching for topics
UlysseDurand Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[codespell]
skip = **/package-lock.json,*.vti,PKG-INFO,**/dist/**,CHANGELOG.md,**/*.js
skip = **/package-lock.json,*.vti,PKG-INFO,**/dist/**,CHANGELOG.md,**/*.js,docs/**.py
ignore-words-list = hist
ignore-regex = name="ba"
12 changes: 12 additions & 0 deletions .github/workflows/website.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ name: Deploy VitePress site to Pages
on:
push:
branches: [master]

# Runs daily at midnight
schedule:
- cron: '0 0 * * *'

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
Expand Down Expand Up @@ -37,6 +41,9 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Python dependencies
working-directory: docs/vitepress
run: "pip install -r requirements.txt"
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Install dependencies
Expand All @@ -45,6 +52,11 @@ jobs:
- name: Update blogs
working-directory: docs/vitepress
run: python update_blogs.py
- name: Fetch trame repos
working-directory: docs/vitepress
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python fetch_repos.py
- name: Build with VitePress
working-directory: docs/vitepress
run: |
Expand Down
1 change: 1 addition & 0 deletions docs/vitepress/.vitepress/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export default defineConfig({
{ text: "How to start", link: "/guide/intro/getting_started" },
{ text: "Cheatsheet", link: "/guide/intro/cheatsheet" },
{ text: "Widgets", link: "/guide/intro/widgets" },
{ text: "Applications", link: "/guide/intro/applications" },
{ text: "Course", link: "/guide/intro/course" },
{ text: "API", link: "/guide/intro/api" },
{ text: "Citing", link: "/guide/intro/citing" },
Expand Down
211 changes: 211 additions & 0 deletions docs/vitepress/.vitepress/theme/RepoList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
<script setup>
import reposDict from '/repos.json'
import { ref, computed } from 'vue'
const repos = Object.entries(reposDict).map(([url, data]) => ({
...data,
url
}))
const props = defineProps({
filterTopic: {
type: String,
required: true
},
displayableTopics: {
type: Object,
required: true
}
})
const activeTopics = ref(new Set())
const search = ref('')
const sortKey = ref('stars')
const sortDir = ref('desc')
const sortOptions = {
name: { label: 'Name (A-Z)', key: r => r.name.toLowerCase() },
stars: { label: 'Stars', key: r => r.stars },
lastCommitDate: { label: 'Last contribution', key: r => new Date(r.lastCommitDate).getTime() },
createdAt: { label: 'Creation date', key: r => new Date(r.createdAt).getTime() },
commitCount: { label: 'Commits', key: r => r.commitCount },
pullRequestCount: { label: 'Pull requests', key: r => r.pullRequestCount },
}
const filtered = computed(() => {
const q = search.value.toLowerCase()
const list = repos.filter(r => {
if (!r.topics.includes(props.filterTopic)) {
return false
}
const matchesTopics =
activeTopics.value.size === 0 ||
[...activeTopics.value].every(activeKey => {
if (activeKey.endsWith('*')) {
const baseKey = activeKey.slice(0, -1);
return r.topics.some(repoTopic => repoTopic.startsWith(baseKey));
}
return r.topics.includes(activeKey);
})
const matchesSearch =
!q ||
r.name.toLowerCase().includes(q) ||
(r.description && r.description.toLowerCase().includes(q)) ||
r.topics.some(t => t.toLowerCase().includes(q))
return matchesTopics && matchesSearch
})
const { key } = sortOptions[sortKey.value]
const dir = sortDir.value === 'asc' ? 1 : -1
return [...list].sort((a, b) => {
const ka = key(a), kb = key(b)
if (ka < kb) return -dir
if (ka > kb) return dir
return 0
})
})
const getDisplayableTagsForRepo = (repoTopics) => {
const result = [];
const seenKeys = new Set();
const topicsMap = props.displayableTopics;
for (const t of repoTopics) {
let matchedKey = null;
// Exact match
if (topicsMap[t]) {
matchedKey = t;
}
// Wildcard match
else {
for (const key in topicsMap) {
if (key.endsWith('*')) {
const baseKey = key.slice(0, -1);
if (t.startsWith(baseKey)) {
matchedKey = key;
break;
}
}
}
}
if (matchedKey && !seenKeys.has(matchedKey)) {
seenKeys.add(matchedKey);
result.push({
key: matchedKey,
githubTopic: t,
label: topicsMap[matchedKey]
});
}
}
return result;
};
const displayableRepoCount = computed(() =>
repos.filter(r => r.topics.includes(props.filterTopic)).length
)
const noTopicSelected = computed(() => activeTopics.value.size === 0)
const clearFilters = () => {
activeTopics.value = new Set()
}
function toggleTopic(t) {
const s = new Set(activeTopics.value)
s.has(t) ? s.delete(t) : s.add(t)
activeTopics.value = s
}
function toggleSortDir() {
sortDir.value = sortDir.value === 'asc' ? 'desc' : 'asc'
}
</script>

<template>
<div class="controls">
<input v-model="search" class="pill" placeholder="Search repos…" />

<select v-model="sortKey" class="pill">
<option v-for="(opt, key) in sortOptions" :key="key" :value="key">
Sort by: {{ opt.label }}
</option>
</select>

<button class="pill" @click="toggleSortDir" :title="sortDir === 'asc' ? 'Ascending' : 'Descending'">
{{ sortDir === 'asc' ? '↑' : '↓' }}
</button>
</div>

<div class="tag-filters">
<div class="tag-filters__buttons">
<button :class="['pill', 'topic', noTopicSelected && 'active']" @click="clearFilters()">
All
</button>
<button
v-for="(label, key) in displayableTopics"
:key="key"
:class="['pill', 'topic', activeTopics.has(key) && 'active']"
@click="toggleTopic(key)"
>
{{ label }}
</button>
</div>
<span class="count">
{{ filtered.length }} / {{ displayableRepoCount }} repos
</span>
</div>

<table>
<thead>
<tr><th>Name</th><th>Description</th><th>Topics</th></tr>
</thead>
<tbody>
<tr v-if="filtered.length === 0">
<td colspan="3">No repos match your filters.</td>
</tr>
<tr v-for="r in filtered" :key="r.name">
<td>
<a :href="r.url" target="_blank">
<img class="repo-img" :src="r.image"/>
</a>
</td>
<td>
<h4 class="repo-title">
<span v-if="!r.trusted" title="Non Kitware-owned">⚠️</span>
<span v-if="r.createdWithinLastYear" title="Created within the last year">🆕</span>
{{ r.name }}
</h4>
{{ r.description || '—' }}
</td>
<td>
<div v-for="tag in getDisplayableTagsForRepo(r.topics)" :key="tag.key">
<a :href="tag.key === '...' ? '' : 'https://github.com/topics/' + tag.githubTopic">
<span :class="['pill', 'topic', activeTopics.has(tag.key) && 'active']">
{{ tag.label }}
</span>
</a>
</div>
</td>
</tr>
</tbody>
</table>
</template>

<style scoped>
.repo-img { max-width: 200px; }
.pill { display: inline-block; padding: 2px 7px; margin: 2px 2px 2px 0; border-radius: 13px; border: 1px solid var(--vp-c-divider); color: var(--vp-c-text-2); background: var(--vp-c-bg); cursor: pointer; }
.repo-title { margin: 0px; }
.tag-filters { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: start; }
.tag-filters__buttons { display: flex; flex-wrap: wrap; gap: 5px; }
.count { white-space: nowrap; padding-top: 2px; }
.topic { margin-bottom: 0; line-height: 1; }
.topic.active { font-weight: bold; }
.topic:hover { color: var(--vp-c-brand-1); }
</style>
68 changes: 68 additions & 0 deletions docs/vitepress/external_repos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
https://github.com/kmarchais/mmgpy:
topics: [trame, trame-app, vtk]
image: "https://github.com/kmarchais/mmgpy/raw/main/assets/mechanical_piece_remeshing.png"

https://github.com/dhruvhaldar/FOAMFlask:
image: "https://github.com/dhruvhaldar/FOAMFlask/raw/dev_pyvista_ts_lkgc/Screenshots/geometry.png"

https://github.com/MBradley1985/SAGE-Viewer:
topics: [trame, trame-app]
image: "https://raw.githubusercontent.com/MBradley1985/SAGE-Viewer/main/docs/images/hero.png"

https://github.com/jwindgassen/jupyter-trame-proxy:
topics: [trame, trame-app, paraview]

https://github.com/utkarshayachit/simplified-batch:
topics: [trame, trame-app, paraview]

https://github.com/vicentebolea/virtual-thermostat:
topics: [trame, trame-app]

https://github.com/linson7017/pymipf:
topics: [trame, trame-app, vtk]
image: "https://github.com/linson7017/pymipf/raw/master/imgs/multi_view.png"

https://github.com/ndminhvn/interactive-population-visualization:
topics: [trame, trame-app, vtk]

https://github.com/Chahat08/BioSET_Visualizer:
topics: [trame, trame-app, vtk]

https://github.com/jph6366/trame-aoc:
topics: [trame, trame-app]

https://github.com/brendanjmeade/fennil:
topics: [trame, trame-app]
image: "https://raw.githubusercontent.com/brendanjmeade/fennil/main/fennil.jpg"

https://github.com/brendanjmeade/parsli:
topics: [trame, trame-app, vtk]
image: "https://raw.githubusercontent.com/brendanjmeade/parsli/refs/heads/main/parsli.png"

https://github.com/XAITK/xaitk-saliency-web-demo:
topics: [trame, trame-app]
image: "https://raw.githubusercontent.com/XAITK/xaitk-saliency-web-demo/master/gallery/xaitk-classification-rise-4.jpg"

https://github.com/festim-dev/festim-gui:
topics: [trame, trame-app, vtk]

https://github.com/cardinalgeo/drilldown:
topics: [trame, trame-app, vtk]
image: "https://github.com/cardinalgeo/drilldown/raw/main/media/poster.jpg"

https://github.com/MXJK851/SpinView:
topics: [trame, trame-app]
image: "https://github.com/MXJK851/SpinView/raw/main/docs/assets/readme.png"

https://gitlab.kitware.com/keu-public/trame-catalyst-demo:
topics: [trame, trame-app, vtk]
nameWithOwner: "keu-public/trame-catalyst-demo"
name: "trame-catalyst-demo"
image: "https://gitlab.kitware.com/keu-public/trame-catalyst-demo/-/raw/main/screenshot.png"
commitCount: 10
createdAt: "2026-05-07T00:00:00Z"
description: "A trame application for Catalyst live visualization."
lastCommitDate: "2026-05-28T00:00:00Z"
pullRequestCount: 0
stars: 0
trusted: true
Loading
Loading