diff --git a/app/Http/Requests/CompaniesRequest.php b/app/Http/Requests/CompaniesRequest.php index e9aa51d5..53002d47 100644 --- a/app/Http/Requests/CompaniesRequest.php +++ b/app/Http/Requests/CompaniesRequest.php @@ -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 diff --git a/resources/scripts/admin/components/modal-components/CompanyModal.vue b/resources/scripts/admin/components/modal-components/CompanyModal.vue index 019a065c..61cdce02 100644 --- a/resources/scripts/admin/components/modal-components/CompanyModal.vue +++ b/resources/scripts/admin/components/modal-components/CompanyModal.vue @@ -48,6 +48,23 @@ /> + + + + 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(/-+$/, '') +} diff --git a/resources/scripts/admin/views/installation/Step7CompanyInfo.vue b/resources/scripts/admin/views/installation/Step7CompanyInfo.vue index 3890ccbd..12a0a6df 100644 --- a/resources/scripts/admin/views/installation/Step7CompanyInfo.vue +++ b/resources/scripts/admin/views/installation/Step7CompanyInfo.vue @@ -34,6 +34,23 @@ /> + + + + - -
diff --git a/resources/scripts/admin/views/settings/CompanyInfoSettings.vue b/resources/scripts/admin/views/settings/CompanyInfoSettings.vue index 357b7dd6..d3723910 100644 --- a/resources/scripts/admin/views/settings/CompanyInfoSettings.vue +++ b/resources/scripts/admin/views/settings/CompanyInfoSettings.vue @@ -28,6 +28,18 @@ /> + + + + @@ -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) ), }, diff --git a/resources/scripts/locales/en.json b/resources/scripts/locales/en.json index 5c224428..7f273fa9 100644 --- a/resources/scripts/locales/en.json +++ b/resources/scripts/locales/en.json @@ -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" -} +} \ No newline at end of file