feat: default notes (#263)

* feat: default notes

* feat: include default invoice note in recurring invoice

* feat: use default export in tw config

* fix: test and naming

* fix: consistent ui for switch in note modal

* feat: little text improvements
This commit is contained in:
Yannic Inselmann
2025-04-05 12:01:06 +02:00
committed by GitHub
parent 2aa17513e1
commit b32c334a71
16 changed files with 110 additions and 26 deletions

View File

@@ -45,6 +45,11 @@
class="mt-2"
/>
</BaseInputGroup>
<BaseSwitchSection
v-model="noteStore.currentNote.is_default"
:title="$t('settings.customization.notes.is_default')"
:description="$t('settings.customization.notes.is_default_description')"
_ />
<BaseInputGroup
:label="$t('settings.customization.notes.notes')"

View File

@@ -14,6 +14,7 @@ import estimateStub from '../stub/estimate'
import estimateItemStub from '../stub/estimate-item'
import taxStub from '../stub/tax'
import { useUserStore } from './user'
import { useNotesStore } from './note'
export const useEstimateStore = (useWindow = false) => {
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
@@ -554,6 +555,7 @@ export const useEstimateStore = (useWindow = false) => {
const taxTypeStore = useTaxTypeStore()
const route = useRoute()
const userStore = useUserStore()
const notesStore = useNotesStore()
this.isFetchingInitialSettings = true
this.newEstimate.selectedCurrency = companyStore.selectedCompanyCurrency
@@ -567,6 +569,8 @@ export const useEstimateStore = (useWindow = false) => {
let editActions = []
if (!isEdit) {
await notesStore.fetchNotes()
this.newEstimate.notes = notesStore.getDefaultNoteForType('Estimate')?.notes
this.newEstimate.tax_per_item =
companyStore.selectedCompanySettings.tax_per_item
this.newEstimate.sales_tax_type = companyStore.selectedCompanySettings.sales_tax_type

View File

@@ -15,6 +15,7 @@ import { useTaxTypeStore } from './tax-type'
import { useCompanyStore } from './company'
import { useItemStore } from './item'
import { useUserStore } from './user'
import { useNotesStore } from './note'
export const useInvoiceStore = (useWindow = false) => {
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
@@ -479,6 +480,7 @@ export const useInvoiceStore = (useWindow = false) => {
const taxTypeStore = useTaxTypeStore()
const route = useRoute()
const userStore = useUserStore()
const notesStore = useNotesStore()
this.isFetchingInitialSettings = true
@@ -491,8 +493,10 @@ export const useInvoiceStore = (useWindow = false) => {
}
let editActions = []
if (!isEdit) {
await notesStore.fetchNotes()
this.newInvoice.notes = notesStore.getDefaultNoteForType('Invoice')?.notes
this.newInvoice.tax_per_item =
companyStore.selectedCompanySettings.tax_per_item
this.newInvoice.sales_tax_type = companyStore.selectedCompanySettings.sales_tax_type

View File

@@ -14,6 +14,7 @@ export const useNotesStore = (useWindow = false) => {
currentNote: {
id: null,
type: '',
is_default: false,
name: '',
notes: '',
},
@@ -24,9 +25,14 @@ export const useNotesStore = (useWindow = false) => {
},
actions: {
getDefaultNoteForType(type) {
return this.notes.find((note) => note.type === type && note.is_default)
},
resetCurrentNote() {
this.currentNote = {
type: '',
is_default: false,
name: '',
notes: '',
}

View File

@@ -6,6 +6,7 @@ import { useCompanyStore } from './company'
import { useNotificationStore } from '@/scripts/stores/notification'
import paymentStub from '../stub/payment'
import { handleError } from '@/scripts/helpers/error-handling'
import { useNotesStore } from './note'
export const usePaymentStore = (useWindow = false) => {
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
@@ -56,6 +57,7 @@ export const usePaymentStore = (useWindow = false) => {
actions: {
fetchPaymentInitialData(isEdit) {
const companyStore = useCompanyStore()
const notesStore = useNotesStore()
const route = useRoute()
this.isFetchingInitialData = true
@@ -80,6 +82,8 @@ export const usePaymentStore = (useWindow = false) => {
// On Create
else if (!isEdit && res2.data) {
await notesStore.fetchNotes()
this.currentPayment.notes = notesStore.getDefaultNoteForType('Payment')?.notes
this.currentPayment.payment_date = moment().format('YYYY-MM-DD')
this.currentPayment.payment_number = res2.data.nextNumber
this.currentPayment.currency =

View File

@@ -14,6 +14,7 @@ import moment from 'moment'
import _ from 'lodash'
import { useInvoiceStore } from './invoice'
import { useNotificationStore } from '@/scripts/stores/notification'
import { useNotesStore } from './note'
export const useRecurringInvoiceStore = (useWindow = false) => {
const defineStoreFunc = useWindow ? window.pinia.defineStore : defineStore
@@ -334,6 +335,7 @@ export const useRecurringInvoiceStore = (useWindow = false) => {
const invoiceStore = useInvoiceStore()
const taxTypeStore = useTaxTypeStore()
const route = useRoute()
const notesStore = useNotesStore()
this.isFetchingInitialSettings = true
this.newRecurringInvoice.currency = companyStore.selectedCompanyCurrency
@@ -348,6 +350,8 @@ export const useRecurringInvoiceStore = (useWindow = false) => {
// on create
if (!isEdit) {
await notesStore.fetchNotes()
this.newRecurringInvoice.notes = notesStore.getDefaultNoteForType('Invoice')?.notes
this.newRecurringInvoice.tax_per_item =
companyStore.selectedCompanySettings.tax_per_item
this.newRecurringInvoice.discount_per_item =

View File

@@ -151,6 +151,7 @@ import { cloneDeep } from 'lodash'
import { useInvoiceStore } from '@/scripts/admin/stores/invoice'
import { useModuleStore } from '@/scripts/admin/stores/module'
import { useNotesStore } from '@/scripts/admin/stores/note'
import { useCompanyStore } from '@/scripts/admin/stores/company'
import { useCustomFieldStore } from '@/scripts/admin/stores/custom-field'
@@ -169,6 +170,8 @@ const invoiceStore = useInvoiceStore()
const companyStore = useCompanyStore()
const customFieldStore = useCustomFieldStore()
const moduleStore = useModuleStore()
const notesStore = useNotesStore()
const { t } = useI18n()
let route = useRoute()
let router = useRouter()

View File

@@ -31,6 +31,10 @@
:load-data="refreshTable"
/>
</template>
<template #cell-name="{ row }">
{{ row.data.name }}
<BaseIcon v-if="row.data.is_default" name="StarIcon" class="w-3 h-3 text-primary-400" />
</template>
<template #cell-type="{ row }">
{{ getLabelNote(row.data.type) }}
</template>
@@ -42,9 +46,7 @@
import { computed, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useModalStore } from '@/scripts/stores/modal'
import { useDialogStore } from '@/scripts/stores/dialog'
import { useNotesStore } from '@/scripts/admin/stores/note'
import { useNotificationStore } from '@/scripts/stores/notification'
import NoteDropdown from '@/scripts/admin/components/dropdowns/NoteIndexDropdown.vue'
import NoteModal from '@/scripts/admin/components/modal-components/NoteModal.vue'
import { useUserStore } from '@/scripts/admin/stores/user'
@@ -53,9 +55,7 @@ import abilities from '@/scripts/admin/stub/abilities'
const { t } = useI18n()
const modalStore = useModalStore()
const dialogStore = useDialogStore()
const noteStore = useNotesStore()
const notificationStore = useNotificationStore()
const userStore = useUserStore()
const table = ref('')
@@ -66,7 +66,7 @@ const notesColumns = computed(() => {
key: 'name',
label: t('settings.customization.notes.name'),
thClass: 'extra',
tdClass: 'font-medium text-gray-900',
tdClass: 'font-medium text-gray-900 flex gap-1 items-center',
},
{
key: 'type',