Files
shopdb-flask/frontend/src/views/applications/ApplicationForm.vue
cproudlock 30dd65674d Initial commit: Shop Database Flask Application
Flask backend with Vue 3 frontend for shop floor machine management.
Includes database schema export for MySQL shopdb_flask database.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 16:07:34 -05:00

272 lines
7.8 KiB
Vue

<template>
<div>
<div class="page-header">
<h2>{{ isEdit ? 'Edit Application' : 'New Application' }}</h2>
</div>
<div class="card">
<div v-if="loading" class="loading">Loading...</div>
<form v-else @submit.prevent="saveApplication">
<div class="form-row">
<div class="form-group">
<label for="appname">Application Name *</label>
<input
id="appname"
v-model="form.appname"
type="text"
class="form-control"
required
/>
</div>
<div class="form-group">
<label for="supportteamid">Support Team</label>
<select
id="supportteamid"
v-model="form.supportteamid"
class="form-control"
>
<option value="">Select team...</option>
<option
v-for="team in supportTeams"
:key="team.supportteamid"
:value="team.supportteamid"
>
{{ team.teamname }}
</option>
</select>
</div>
</div>
<div class="form-group">
<label for="appdescription">Description</label>
<textarea
id="appdescription"
v-model="form.appdescription"
class="form-control"
rows="2"
></textarea>
</div>
<h4 style="margin-top: 1.5rem; margin-bottom: 1rem;">Application Flags</h4>
<div class="form-row">
<div class="form-group checkbox-group">
<label>
<input type="checkbox" v-model="form.isinstallable" />
Installable
</label>
<label>
<input type="checkbox" v-model="form.islicenced" />
Licensed
</label>
<label>
<input type="checkbox" v-model="form.isprinter" />
Printer App
</label>
<label>
<input type="checkbox" v-model="form.ishidden" />
Hidden
</label>
</div>
</div>
<h4 style="margin-top: 1.5rem; margin-bottom: 1rem;">Links & Paths</h4>
<div class="form-row">
<div class="form-group">
<label for="applicationlink">Application Link</label>
<input
id="applicationlink"
v-model="form.applicationlink"
type="text"
class="form-control"
placeholder="https://..."
/>
</div>
<div class="form-group">
<label for="documentationpath">Documentation Path</label>
<input
id="documentationpath"
v-model="form.documentationpath"
type="text"
class="form-control"
placeholder="URL or file path"
/>
</div>
</div>
<div class="form-group">
<label for="installpath">Install Path</label>
<input
id="installpath"
v-model="form.installpath"
type="text"
class="form-control"
placeholder="Network path or URL to install files"
/>
</div>
<div class="form-group">
<label for="image">Image Filename</label>
<input
id="image"
v-model="form.image"
type="text"
class="form-control"
placeholder="e.g., myapp.png"
/>
<small class="form-hint">Image should be placed in /images/applications/</small>
</div>
<h4 style="margin-top: 1.5rem; margin-bottom: 1rem;">Notes</h4>
<div class="form-group">
<label for="applicationnotes">Application Notes (HTML supported)</label>
<textarea
id="applicationnotes"
v-model="form.applicationnotes"
class="form-control"
rows="6"
placeholder="Enter notes... HTML tags like <BR>, <a>, <strong> are supported"
></textarea>
</div>
<div v-if="error" class="error-message">{{ error }}</div>
<div style="display: flex; gap: 0.5rem; margin-top: 1.5rem;">
<button type="submit" class="btn btn-primary" :disabled="saving">
{{ saving ? 'Saving...' : 'Save Application' }}
</button>
<router-link to="/applications" class="btn btn-secondary">Cancel</router-link>
</div>
</form>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { applicationsApi } from '../../api'
const route = useRoute()
const router = useRouter()
const isEdit = computed(() => !!route.params.id)
const loading = ref(true)
const saving = ref(false)
const error = ref('')
const form = ref({
appname: '',
appdescription: '',
supportteamid: '',
isinstallable: false,
islicenced: false,
isprinter: false,
ishidden: false,
applicationlink: '',
documentationpath: '',
installpath: '',
image: '',
applicationnotes: ''
})
const supportTeams = ref([])
onMounted(async () => {
try {
// Load support teams
const teamsRes = await applicationsApi.getSupportTeams()
supportTeams.value = teamsRes.data.data || []
// Load application if editing
if (isEdit.value) {
const response = await applicationsApi.get(route.params.id)
const app = response.data.data
form.value = {
appname: app.appname || '',
appdescription: app.appdescription || '',
supportteamid: app.supportteam?.supportteamid || '',
isinstallable: app.isinstallable || false,
islicenced: app.islicenced || false,
isprinter: app.isprinter || false,
ishidden: app.ishidden || false,
applicationlink: app.applicationlink || '',
documentationpath: app.documentationpath || '',
installpath: app.installpath || '',
image: app.image || '',
applicationnotes: app.applicationnotes || ''
}
}
} catch (err) {
console.error('Error loading data:', err)
error.value = 'Failed to load data'
} finally {
loading.value = false
}
})
async function saveApplication() {
error.value = ''
saving.value = true
try {
const appData = {
appname: form.value.appname,
appdescription: form.value.appdescription || null,
supportteamid: form.value.supportteamid || null,
isinstallable: form.value.isinstallable,
islicenced: form.value.islicenced,
isprinter: form.value.isprinter,
ishidden: form.value.ishidden,
applicationlink: form.value.applicationlink || null,
documentationpath: form.value.documentationpath || null,
installpath: form.value.installpath || null,
image: form.value.image || null,
applicationnotes: form.value.applicationnotes || null
}
if (isEdit.value) {
await applicationsApi.update(route.params.id, appData)
} else {
await applicationsApi.create(appData)
}
router.push('/applications')
} catch (err) {
console.error('Error saving application:', err)
error.value = err.response?.data?.message || 'Failed to save application'
} finally {
saving.value = false
}
}
</script>
<style scoped>
.checkbox-group {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
.checkbox-group label {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
}
.form-hint {
display: block;
margin-top: 0.25rem;
font-size: 0.8rem;
color: var(--text-light, #666);
}
</style>