Skip to content

Commit 9185689

Browse files
authored
feat(medcat-trainer): load mctee frontend bundle (#573)
* feat(medcat-trainer): plugin-slot for mct-ee licence badge. * feat(medcat-trainer): wire MCT EE plugin loading and MedCAT Service form handler * feat(medcat-trainer): fix frontend vite config
1 parent 6366705 commit 9185689

6 files changed

Lines changed: 79 additions & 3 deletions

File tree

medcat-trainer/webapp/frontend/env.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,8 @@ declare module 'tiny-emitter/instance' {
1515
const emitter: TinyEmitterInstance
1616
export default emitter
1717
}
18+
19+
declare module '@mctee/enterprise' {
20+
const plugin: unknown
21+
export default plugin
22+
}

medcat-trainer/webapp/frontend/src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {authPlugin} from "./auth";
2626
import { loadRuntimeConfig, isOidcEnabled } from './runtimeConfig';
2727
import { registerUnauthorizedInterceptor } from './httpAuth'
2828
import { initPluginBootstrap } from './plugins/bootstrap'
29+
import { loadEnterprisePlugin } from './plugins/enterprise'
2930
import PluginSlot from '@/components/plugins/PluginSlot.vue'
3031

3132
const theme ={
@@ -52,6 +53,7 @@ const vuetify = createVuetify({
5253

5354
async function bootstrap() {
5455
await loadRuntimeConfig();
56+
await loadEnterprisePlugin()
5557

5658
const app = createApp(App)
5759
app.config.globalProperties.$http = axios
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* No-op stand-in for ``@mctee/enterprise`` when VITE_MCT_EE is not enabled.
3+
* Keeps OSS ``vite`` / ``vite build`` resolving the dynamic import in
4+
* ``enterprise.ts`` without requiring the private EE package.
5+
*/
6+
export {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Load the MedCAT Trainer Enterprise frontend plugin when VITE_MCT_EE=1.
3+
*
4+
* Local dev: set MCT_EE_ROOT to the ``medcat-trainer-ee/frontend/src`` folder and
5+
* run the OSS frontend with ``VITE_MCT_EE=1 npm run dev``.
6+
*/
7+
export async function loadEnterprisePlugin(): Promise<void> {
8+
if (import.meta.env.VITE_MCT_EE !== '1') {
9+
return
10+
}
11+
try {
12+
await import('@mctee/enterprise')
13+
console.info('[Bootstrap] Enterprise plugin loaded')
14+
} catch (error) {
15+
console.warn('[Bootstrap] Enterprise plugin not loaded:', error)
16+
}
17+
}

medcat-trainer/webapp/frontend/src/views/ProjectAdmin.vue

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,10 @@
463463

464464
<!-- Model Packs Tab -->
465465
<div v-if="activeTab === 'modelpacks'" class="tab-content admin-section">
466-
<plugin-slot name="project-admin:modelpacks" />
466+
<plugin-slot
467+
name="project-admin:modelpacks"
468+
@model-service-linked="onMedcatteryModelLinked"
469+
/>
467470
<model-packs-list
468471
v-if="!showModelPackForm && !editingModelPack"
469472
:model-packs="modelPacks"
@@ -699,6 +702,32 @@ export default {
699702
const response = await this.$http.get('/api/modelpacks/')
700703
this.modelPacks = response.data.results || response.data
701704
},
705+
async onMedcatteryModelLinked(payload) {
706+
if (payload?.modelServiceUrl) {
707+
this.formData.use_model_service = true
708+
this.formData.model_service_url = payload.modelServiceUrl
709+
this.formData.model_pack = null
710+
this.formData.concept_db = null
711+
this.formData.vocab = null
712+
if (this.validationErrors.model_pack) {
713+
delete this.validationErrors.model_pack
714+
}
715+
if (this.validationErrors.concept_db) {
716+
delete this.validationErrors.concept_db
717+
}
718+
if (this.validationErrors.vocab) {
719+
delete this.validationErrors.vocab
720+
}
721+
if (this.validationErrors.model_config) {
722+
delete this.validationErrors.model_config
723+
}
724+
if (this.validationErrors.model_service_url) {
725+
delete this.validationErrors.model_service_url
726+
}
727+
}
728+
const label = payload?.label || 'model'
729+
this.$toast?.success(`Linked ${label} via MedCAT Service`)
730+
},
702731
async fetchUsers() {
703732
const response = await this.$http.get('/api/users/')
704733
this.users = response.data.results || response.data

medcat-trainer/webapp/frontend/vite.config.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
import { fileURLToPath, URL } from 'node:url'
2+
import path from 'node:path'
23

3-
import { defineConfig } from 'vite'
4+
import { defineConfig, loadEnv } from 'vite'
45
import vue from '@vitejs/plugin-vue'
56

7+
// Resolve env at module load so this stays a plain object. vitest.config.ts
8+
// uses mergeConfig(), which cannot merge callback-style Vite configs.
9+
const env = {
10+
...loadEnv(process.env.MODE || process.env.NODE_ENV || 'development', process.cwd(), ''),
11+
...process.env,
12+
}
13+
const mctEeRoot = env.MCT_EE_ROOT || path.resolve(
14+
fileURLToPath(new URL('../../../../cogstack-private/medcat-trainer-ee/frontend/src', import.meta.url))
15+
)
16+
617
// https://vite.dev/config/
718
export default defineConfig({
819
plugins: [
@@ -11,7 +22,13 @@ export default defineConfig({
1122
resolve: {
1223
alias: {
1324
vue: 'vue/dist/vue.esm-bundler.js',
14-
'@': fileURLToPath(new URL('./src', import.meta.url))
25+
'@': fileURLToPath(new URL('./src', import.meta.url)),
26+
// Always resolve so Vite/Rollup can analyse the dynamic import in
27+
// enterprise.ts. OSS builds get a local noop stub; EE builds point at
28+
// the private package when VITE_MCT_EE=1.
29+
'@mctee/enterprise': env.VITE_MCT_EE === '1'
30+
? path.join(mctEeRoot, 'index.ts')
31+
: fileURLToPath(new URL('./src/plugins/enterprise-stub.ts', import.meta.url)),
1532
}
1633
},
1734
build: {

0 commit comments

Comments
 (0)