added company slug

This commit is contained in:
asift798
2022-03-14 17:45:58 +05:30
parent 0e31f85c18
commit 20c2502e31
5 changed files with 141 additions and 10 deletions

View File

@ -33,7 +33,7 @@ class CompaniesRequest extends FormRequest
'currency' => [
'required'
],
'currency' => [
'slug' => [
'required'
],
'address.name' => [
@ -70,7 +70,8 @@ class CompaniesRequest extends FormRequest
{
return collect($this->validated())
->only([
'name'
'name',
'slug'
])
->merge([
'owner_id' => $this->user()->id

View File

@ -48,6 +48,23 @@
/>
</BaseInputGroup>
<BaseInputGroup
:label="$tc('settings.company_info.company_slug')"
:error="
v$.newCompanyForm.slug.$error &&
v$.newCompanyForm.slug.$errors[0].$message
"
:content-loading="isFetchingInitialData"
required
>
<BaseInput
v-model="newCompanyForm.slug"
:invalid="v$.newCompanyForm.slug.$error"
:content-loading="isFetchingInitialData"
@input="v$.newCompanyForm.slug.$touch()"
/>
</BaseInputGroup>
<BaseInputGroup
:content-loading="isFetchingInitialData"
:label="$tc('settings.company_info.country')"
@ -130,7 +147,7 @@
<script setup>
import { useModalStore } from '@/scripts/stores/modal'
import { computed, onMounted, ref, reactive } from 'vue'
import { computed, onMounted, ref, reactive, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { required, minLength, helpers } from '@vuelidate/validators'
import { useVuelidate } from '@vuelidate/core'
@ -152,6 +169,7 @@ let companyLogoName = ref(null)
const newCompanyForm = reactive({
name: null,
slug: null,
currency: '',
address: {
country_id: null,
@ -162,6 +180,9 @@ const modalActive = computed(() => {
return modalStore.active && modalStore.componentName === 'CompanyModal'
})
const slugValidator = (value) => {
return value == slugify(value)
}
const rules = {
newCompanyForm: {
name: {
@ -171,6 +192,17 @@ const rules = {
minLength(3)
),
},
slug: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
slugValidator: helpers.withMessage(
t('validation.invalid_slug'),
slugValidator
),
},
address: {
country_id: {
required: helpers.withMessage(t('validation.required'), required),
@ -243,6 +275,7 @@ async function submitCompanyData() {
function resetNewCompanyForm() {
newCompanyForm.name = ''
newCompanyForm.slug = ''
newCompanyForm.currency = ''
newCompanyForm.address.country_id = ''
@ -257,4 +290,24 @@ function closeCompanyModal() {
v$.value.$reset()
}, 300)
}
// watcher for if change company name then auto fill company slug value
watch(
() => newCompanyForm.name,
(currentValue) => {
newCompanyForm.slug = slugify(currentValue)
}
)
function slugify(string) {
return string
.toString()
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^\w\-]+/g, '')
.replace(/\-\-+/g, '-')
.replace(/^-+/, '')
.replace(/-+$/, '')
}
</script>

View File

@ -34,6 +34,23 @@
/>
</BaseInputGroup>
<BaseInputGroup
:label="$tc('wizard.company_slug')"
:error="
v$.companyForm.slug.$error &&
v$.companyForm.slug.$errors[0].$message
"
required
>
<BaseInput
v-model="companyForm.slug"
:invalid="v$.companyForm.slug.$error"
type="text"
name="slug"
@input="v$.companyForm.slug.$touch()"
/>
</BaseInputGroup>
<BaseInputGroup
:label="$t('wizard.country')"
:error="
@ -57,9 +74,7 @@
track-by="name"
/>
</BaseInputGroup>
</div>
<div class="grid grid-cols-1 gap-4 mb-4 md:grid-cols-2 md:mb-6">
<BaseInputGroup :label="$t('wizard.state')">
<BaseInput
v-model="companyForm.address.state"
@ -144,9 +159,9 @@
</template>
<script setup>
import { ref, computed, onMounted, reactive } from 'vue'
import { ref, computed, onMounted, reactive, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { required, maxLength, helpers } from '@vuelidate/validators'
import { required, minLength, maxLength, helpers } from '@vuelidate/validators'
import { useVuelidate } from '@vuelidate/core'
import { useGlobalStore } from '@/scripts/admin/stores/global'
import { useCompanyStore } from '@/scripts/admin/stores/company'
@ -162,6 +177,7 @@ let logoFileName = ref(null)
const companyForm = reactive({
name: null,
slug: null,
address: {
address_street_1: '',
address_street_2: '',
@ -188,10 +204,28 @@ onMounted(async () => {
})?.id
})
const slugValidator = (value) => {
return value == slugify(value)
}
const rules = {
companyForm: {
name: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
},
slug: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
slugValidator: helpers.withMessage(
t('validation.invalid_slug'),
slugValidator
),
},
address: {
country_id: {
@ -249,4 +283,24 @@ async function next() {
emit('next', 7)
}
}
// watcher for if change company name then auto fill company slug value
watch(
() => companyForm.name,
(currentValue) => {
companyForm.slug = slugify(currentValue)
}
)
function slugify(string) {
return string
.toString()
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^\w\-]+/g, '')
.replace(/\-\-+/g, '-')
.replace(/^-+/, '')
.replace(/-+$/, '')
}
</script>

View File

@ -28,6 +28,18 @@
/>
</BaseInputGroup>
<BaseInputGroup
:label="$tc('settings.company_info.company_slug')"
:error="v$.slug.$error && v$.slug.$errors[0].$message"
required
>
<BaseInput
v-model="companyForm.slug"
:invalid="v$.slug.$error"
@blur="v$.slug.$touch()"
/>
</BaseInputGroup>
<BaseInputGroup :label="$tc('settings.company_info.phone')">
<BaseInput v-model="companyForm.address.phone" />
</BaseInputGroup>
@ -160,6 +172,7 @@ let isSaving = ref(false)
const companyForm = reactive({
name: null,
slug: null,
logo: null,
address: {
address_street_1: '',
@ -193,7 +206,14 @@ const rules = computed(() => {
name: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length'),
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
},
slug: {
required: helpers.withMessage(t('validation.required'), required),
minLength: helpers.withMessage(
t('validation.name_min_length', { count: 3 }),
minLength(3)
),
},

View File

@ -863,6 +863,7 @@
"company_info": {
"company_info": "Company info",
"company_name": "Company Name",
"company_slug": "Company Slug",
"company_logo": "Company Logo",
"section_description": "Information about your company that will be displayed on invoices, estimates and other documents created by Crater.",
"phone": "Phone",
@ -1324,6 +1325,7 @@
"company_info": "Company Information",
"company_info_desc": "This information will be displayed on invoices. Note that you can edit this later on settings page.",
"company_name": "Company Name",
"company_slug": "Company Slug",
"company_logo": "Company Logo",
"logo_preview": "Logo Preview",
"preferences": "Company Preferences",
@ -1454,7 +1456,8 @@
"at_least_one_ability": "Please select atleast one Permission.",
"valid_driver_key": "Please enter a valid {driver} key.",
"valid_exchange_rate": "Please enter a valid exchange rate.",
"company_name_not_same": "Company name must match with given name."
"company_name_not_same": "Company name must match with given name.",
"invalid_slug": "Invalid Slug"
},
"errors": {
"starter_plan": "This feature is available on Starter plan and onwards!",
@ -1523,4 +1526,4 @@
"pdf_ship_to": "Ship to,",
"pdf_received_from": "Received from:",
"pdf_tax_label": "Tax"
}
}