diff --git a/deploy/windows/web.config b/deploy/windows/web.config
index 4821797..b5b0704 100644
--- a/deploy/windows/web.config
+++ b/deploy/windows/web.config
@@ -76,4 +76,39 @@
-->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/utils/basePath.js b/frontend/src/utils/basePath.js
index b77cbbb..a9db043 100644
--- a/frontend/src/utils/basePath.js
+++ b/frontend/src/utils/basePath.js
@@ -12,6 +12,24 @@ export function withBase(path) {
return BASE_URL + String(path).replace(/^\//, '')
}
+// Resolve a stored file/link path for use in an . Full URLs (http,
+// https, file:, mailto:, ...) and UNC / protocol-relative paths (\\server,
+// //host) open as-is. A path relative to the app (e.g. 'installers/x.exe' or
+// './installers/x.exe') is mounted under the base so it does NOT resolve
+// against the current route - '/shopdb/applications/6' + 'installers/x.exe'
+// wrongly became '/shopdb/applications/installers/x.exe'.
+export function fileHref(path) {
+ if (!path) return null
+ const trimmed = String(path).trim()
+ if (!trimmed) return null
+ if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)
+ || trimmed.startsWith('\\\\')
+ || trimmed.startsWith('//')) {
+ return trimmed
+ }
+ return withBase('/' + trimmed.replace(/^(\.?\/)+/, ''))
+}
+
// Inverse of withBase: turn a browser pathname (which includes the mount
// base, e.g. '/ops/computers') into a router path ('/computers'). Router
// navigation already applies the base; feeding it an un-stripped pathname
diff --git a/plugins/applications/frontend/views/ApplicationDetail.vue b/plugins/applications/frontend/views/ApplicationDetail.vue
index aa5da35..833df5c 100644
--- a/plugins/applications/frontend/views/ApplicationDetail.vue
+++ b/plugins/applications/frontend/views/ApplicationDetail.vue
@@ -31,13 +31,13 @@
Hidden
@@ -167,6 +167,7 @@ import { useRoute } from 'vue-router'
import { applicationsApi } from '@/api'
import { getContactEmailDomain } from '@/utils/siteSettings'
import { sanitizeNotesHtml } from '@/utils/sanitizeHtml'
+import { fileHref } from '@/utils/basePath'
const route = useRoute()
diff --git a/plugins/applications/frontend/views/ApplicationsList.vue b/plugins/applications/frontend/views/ApplicationsList.vue
index 3a7c6ec..5116c12 100644
--- a/plugins/applications/frontend/views/ApplicationsList.vue
+++ b/plugins/applications/frontend/views/ApplicationsList.vue
@@ -41,15 +41,15 @@
|
-
+
⬇
-
+
🔗
|
-
+
📄
|
@@ -102,6 +102,7 @@ import { ref, onMounted } from 'vue'
import { applicationsApi } from '@/api'
import PaginationBar from '@/components/PaginationBar.vue'
import { useListQuery } from '@/composables/listQuery'
+import { fileHref } from '@/utils/basePath'
const applications = ref([])
const loading = ref(true)