ADR-013 Phase 4 complete: all plugin frontends self-contained + lint rule
This commit is contained in:
@@ -28,24 +28,6 @@ export default [
|
||||
name: 'reports',
|
||||
component: () => import('../../views/reports/ReportsIndex.vue')
|
||||
},
|
||||
{
|
||||
path: 'reports/pc-relationships',
|
||||
name: 'report-pc-relationships',
|
||||
component: () => import('../../views/reports/PCRelationshipsReport.vue'),
|
||||
meta: { plugin: 'computers' }
|
||||
},
|
||||
{
|
||||
path: 'reports/toner',
|
||||
name: 'toner-report',
|
||||
component: () => import('../../views/reports/TonerReport.vue'),
|
||||
meta: { plugin: 'printers' }
|
||||
},
|
||||
{
|
||||
path: 'employees/:sso',
|
||||
name: 'employee-detail',
|
||||
component: () => import('../../views/employees/EmployeeDetail.vue'),
|
||||
meta: { plugin: 'employees' }
|
||||
},
|
||||
// Settings
|
||||
{
|
||||
path: 'settings',
|
||||
@@ -107,30 +89,6 @@ export default [
|
||||
component: () => import('../../views/settings/SiteSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/slides',
|
||||
name: 'slide-manager',
|
||||
component: () => import('../../views/settings/SlideManager.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'slides' }
|
||||
},
|
||||
{
|
||||
path: 'settings/machinetypes',
|
||||
name: 'machinetypes',
|
||||
component: () => import('../../views/settings/MachineTypesList.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/networktypes',
|
||||
name: 'network-types',
|
||||
component: () => import('../../views/settings/NetworkTypesList.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/printertypes',
|
||||
name: 'printer-types',
|
||||
component: () => import('../../views/settings/PrinterTypesList.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/relationshiptypes',
|
||||
name: 'relationship-types',
|
||||
@@ -155,12 +113,6 @@ export default [
|
||||
component: () => import('../../views/settings/CustomFieldsList.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/employeedirectory',
|
||||
name: 'employee-directory',
|
||||
component: () => import('../../views/settings/EmployeeDirectory.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
// The old monolithic System Settings tab page is split into one routed page
|
||||
// per section (below). This redirect keeps old bookmarks working: bare
|
||||
// /settings/system and every /settings/system?tab=<key> land on the right page.
|
||||
@@ -192,24 +144,6 @@ export default [
|
||||
component: () => import('../../views/settings/ServiceNowSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/zabbix',
|
||||
name: 'zabbix-settings',
|
||||
component: () => import('../../views/settings/ZabbixSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/dellwarranty',
|
||||
name: 'dell-warranty-settings',
|
||||
component: () => import('../../views/settings/DellWarrantySettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/pctypemapping',
|
||||
name: 'pctype-mapping-settings',
|
||||
component: () => import('../../views/settings/PCTypeMappingSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true }
|
||||
},
|
||||
{
|
||||
path: 'settings/branding',
|
||||
name: 'branding-settings',
|
||||
|
||||
@@ -2,6 +2,18 @@
|
||||
* Computers plugin routes
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: 'reports/pc-relationships',
|
||||
name: 'report-pc-relationships',
|
||||
component: () => import('./views/PCRelationshipsReport.vue'),
|
||||
meta: { plugin: 'computers' }
|
||||
},
|
||||
{
|
||||
path: 'settings/pctypemapping',
|
||||
name: 'pctype-mapping-settings',
|
||||
component: () => import('./views/PCTypeMappingSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'computers' }
|
||||
},
|
||||
{
|
||||
path: 'pcs',
|
||||
name: 'pcs',
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { reportsApi } from '../../api'
|
||||
import { reportsApi } from '@/api'
|
||||
|
||||
const loading = ref(true)
|
||||
const data = ref([])
|
||||
18
plugins/employees/frontend/routes.js
Normal file
18
plugins/employees/frontend/routes.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Employees plugin frontend routes (ADR-013 Phase 4). Extracted from core.js -
|
||||
* employee detail + the directory settings page belong to the employees plugin.
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: 'employees/:sso',
|
||||
name: 'employee-detail',
|
||||
component: () => import('./views/EmployeeDetail.vue'),
|
||||
meta: { plugin: 'employees' }
|
||||
},
|
||||
{
|
||||
path: 'settings/employeedirectory',
|
||||
name: 'employee-directory',
|
||||
component: () => import('./views/EmployeeDirectory.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'employees' }
|
||||
}
|
||||
]
|
||||
@@ -149,10 +149,10 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { withBase } from '../../utils/basePath'
|
||||
import { withBase } from '@/utils/basePath'
|
||||
import { employeesApi, usbApi, notificationsApi } from '@/api'
|
||||
import { isPluginEnabled, loadEnabledPlugins } from '@/composables/enabledPlugins'
|
||||
import { useToast } from '../../composables/toast'
|
||||
import { useToast } from '@/composables/toast'
|
||||
const toast = useToast()
|
||||
|
||||
const route = useRoute()
|
||||
@@ -134,9 +134,9 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { employeesApi, settingsApi } from '../../api'
|
||||
import { useToast } from '../../composables/toast'
|
||||
import { apiError } from '../../utils/apiError'
|
||||
import { employeesApi, settingsApi } from '@/api'
|
||||
import { useToast } from '@/composables/toast'
|
||||
import { apiError } from '@/utils/apiError'
|
||||
|
||||
const toast = useToast()
|
||||
const selfhosted = ref(false)
|
||||
@@ -2,6 +2,12 @@
|
||||
* Machines plugin routes
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: 'settings/machinetypes',
|
||||
name: 'machinetypes',
|
||||
component: () => import('./views/MachineTypesList.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'machines' }
|
||||
},
|
||||
{
|
||||
path: 'machines',
|
||||
name: 'machines',
|
||||
|
||||
@@ -73,11 +73,11 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { machinesApi } from '../../api'
|
||||
import { machinesApi } from '@/api'
|
||||
import ColorSwatchPicker from '@/components/ColorSwatchPicker.vue'
|
||||
import { colorStyle } from '@/utils/colorStyle'
|
||||
import { useToast } from '../../composables/toast'
|
||||
import { apiError } from '../../utils/apiError'
|
||||
import { useToast } from '@/composables/toast'
|
||||
import { apiError } from '@/utils/apiError'
|
||||
const toast = useToast()
|
||||
|
||||
const items = ref([])
|
||||
@@ -2,6 +2,12 @@
|
||||
* Network plugin routes
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: 'settings/networktypes',
|
||||
name: 'network-types',
|
||||
component: () => import('./views/NetworkTypesList.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'network' }
|
||||
},
|
||||
{
|
||||
path: 'network',
|
||||
name: 'network',
|
||||
|
||||
@@ -73,11 +73,11 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { networkApi } from '../../api'
|
||||
import { networkApi } from '@/api'
|
||||
import ColorSwatchPicker from '@/components/ColorSwatchPicker.vue'
|
||||
import { colorStyle } from '@/utils/colorStyle'
|
||||
import { useToast } from '../../composables/toast'
|
||||
import { apiError } from '../../utils/apiError'
|
||||
import { useToast } from '@/composables/toast'
|
||||
import { apiError } from '@/utils/apiError'
|
||||
const toast = useToast()
|
||||
|
||||
const items = ref([])
|
||||
@@ -2,6 +2,24 @@
|
||||
* Printers plugin routes
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: 'reports/toner',
|
||||
name: 'toner-report',
|
||||
component: () => import('./views/TonerReport.vue'),
|
||||
meta: { plugin: 'printers' }
|
||||
},
|
||||
{
|
||||
path: 'settings/printertypes',
|
||||
name: 'printer-types',
|
||||
component: () => import('./views/PrinterTypesList.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'printers' }
|
||||
},
|
||||
{
|
||||
path: 'settings/zabbix',
|
||||
name: 'zabbix-settings',
|
||||
component: () => import('./views/ZabbixSettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'printers' }
|
||||
},
|
||||
{
|
||||
path: 'printers',
|
||||
name: 'printers',
|
||||
|
||||
@@ -73,11 +73,11 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { printersApi } from '../../api'
|
||||
import { printersApi } from '@/api'
|
||||
import ColorSwatchPicker from '@/components/ColorSwatchPicker.vue'
|
||||
import { colorStyle } from '@/utils/colorStyle'
|
||||
import { useToast } from '../../composables/toast'
|
||||
import { apiError } from '../../utils/apiError'
|
||||
import { useToast } from '@/composables/toast'
|
||||
import { apiError } from '@/utils/apiError'
|
||||
const toast = useToast()
|
||||
|
||||
const items = ref([])
|
||||
@@ -101,7 +101,7 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { printersApi } from '@/api'
|
||||
import EmailReportButton from '../../components/EmailReportButton.vue'
|
||||
import EmailReportButton from '@/components/EmailReportButton.vue'
|
||||
|
||||
const emailColumns = [
|
||||
{ key: 'printer', label: 'Printer' },
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
<script setup>
|
||||
import { onMounted, computed } from 'vue'
|
||||
import { useSystemSettings } from '../../composables/systemSettings'
|
||||
import { useSystemSettings } from '@/composables/systemSettings'
|
||||
|
||||
const {
|
||||
settings, saving, error, success,
|
||||
@@ -1,4 +1,13 @@
|
||||
|
||||
export default [
|
||||
{
|
||||
path: 'settings/slides',
|
||||
name: 'slide-manager',
|
||||
component: () => import('./views/SlideManager.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'slides' }
|
||||
}
|
||||
]
|
||||
|
||||
export const toplevel = [
|
||||
{
|
||||
path: '/tv',
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
* Warranty plugin routes
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: 'settings/dellwarranty',
|
||||
name: 'dell-warranty-settings',
|
||||
component: () => import('./views/DellWarrantySettings.vue'),
|
||||
meta: { requiresAuth: true, requiresAdmin: true, plugin: 'warranty' }
|
||||
},
|
||||
{
|
||||
path: 'warranties',
|
||||
name: 'warranties',
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
<script setup>
|
||||
import { onMounted, computed } from 'vue'
|
||||
import { useSystemSettings } from '../../composables/systemSettings'
|
||||
import { useSystemSettings } from '@/composables/systemSettings'
|
||||
|
||||
const {
|
||||
settings, saving, error, success,
|
||||
@@ -106,6 +106,23 @@ if [ -n "$SNAKE_FE" ]; then
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
|
||||
# ADR-013 Phase 4: a plugin frontend (plugins/<name>/frontend/) may import core
|
||||
# via the @/ alias or its own tree (./, ../ within the plugin), never another
|
||||
# plugin's tree and never an escaping ../../ into src. Keeps plugin frontends
|
||||
# self-contained so a per-site build can drop one cleanly.
|
||||
echo "==> Checking for cross-plugin / escaping imports in plugin frontends..."
|
||||
if [ -d plugins ]; then
|
||||
PLUGIN_FE_IMPORTS=$(grep -rPn "(import|from)\s+['\"]([^'\"]*\.\./\.\./|[^'\"]*/plugins/)" \
|
||||
--include='*.vue' --include='*.js' plugins/*/frontend/ 2>/dev/null || true)
|
||||
if [ -n "$PLUGIN_FE_IMPORTS" ]; then
|
||||
echo "FAIL: plugin frontend imports must use the @/ alias for core, not"
|
||||
echo " an escaping ../../ or another plugin's path:"
|
||||
echo "$PLUGIN_FE_IMPORTS"
|
||||
echo
|
||||
VIOLATIONS=$((VIOLATIONS + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$VIOLATIONS" -gt 0 ]; then
|
||||
echo "=================================================="
|
||||
echo "$VIOLATIONS naming/style violation(s) found."
|
||||
|
||||
Reference in New Issue
Block a user