Merge pull request #384 from frappe/develop
chore: Merge develop to main
This commit is contained in:
commit
6a7793b721
@ -611,10 +611,10 @@ def get_field_obj(field):
|
|||||||
"all_properties": field,
|
"all_properties": field,
|
||||||
}
|
}
|
||||||
|
|
||||||
obj["placeholder"] = "Add " + field.label + "..."
|
obj["placeholder"] = field.placeholder or "Add " + field.label + "..."
|
||||||
|
|
||||||
if field.fieldtype == "Link":
|
if field.fieldtype == "Link":
|
||||||
obj["placeholder"] = "Select " + field.label + "..."
|
obj["placeholder"] = field.placeholder or "Select " + field.label + "..."
|
||||||
obj["doctype"] = field.options
|
obj["doctype"] = field.options
|
||||||
elif field.fieldtype == "Select" and field.options:
|
elif field.fieldtype == "Select" and field.options:
|
||||||
obj["options"] = [{"label": option, "value": option} for option in field.options.split("\n")]
|
obj["options"] = [{"label": option, "value": option} for option in field.options.split("\n")]
|
||||||
@ -686,6 +686,7 @@ def get_fields(doctype: str, allow_all_fieldtypes: bool = False):
|
|||||||
"mandatory_depends_on": field.mandatory_depends_on,
|
"mandatory_depends_on": field.mandatory_depends_on,
|
||||||
"read_only_depends_on": field.read_only_depends_on,
|
"read_only_depends_on": field.read_only_depends_on,
|
||||||
"link_filters": field.get("link_filters"),
|
"link_filters": field.get("link_filters"),
|
||||||
|
"placeholder": field.placeholder,
|
||||||
})
|
})
|
||||||
|
|
||||||
return _fields
|
return _fields
|
||||||
|
|||||||
@ -48,6 +48,7 @@ def get_notifications():
|
|||||||
def mark_as_read(user=None, doc=None):
|
def mark_as_read(user=None, doc=None):
|
||||||
user = user or frappe.session.user
|
user = user or frappe.session.user
|
||||||
filters = {"to_user": user, "read": False}
|
filters = {"to_user": user, "read": False}
|
||||||
|
or_filters = []
|
||||||
if doc:
|
if doc:
|
||||||
or_filters = [
|
or_filters = [
|
||||||
{"comment": doc},
|
{"comment": doc},
|
||||||
|
|||||||
@ -44,6 +44,7 @@ def get_fields_layout(doctype: str, type: str):
|
|||||||
"type": field.fieldtype,
|
"type": field.fieldtype,
|
||||||
"options": field.options,
|
"options": field.options,
|
||||||
"mandatory": field.reqd,
|
"mandatory": field.reqd,
|
||||||
|
"placeholder": field.placeholder,
|
||||||
}
|
}
|
||||||
section["fields"][section.get("fields").index(field["name"])] = field
|
section["fields"][section.get("fields").index(field["name"])] = field
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ frappe.ui.form.on("CRM Form Script", {
|
|||||||
function setupForm({ doc }) {
|
function setupForm({ doc }) {
|
||||||
return {
|
return {
|
||||||
actions: [],
|
actions: [],
|
||||||
|
statuses: [],
|
||||||
}
|
}
|
||||||
}`.trim();
|
}`.trim();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,7 +125,6 @@ import { computed } from 'vue'
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
fields: {
|
fields: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
|
||||||
},
|
},
|
||||||
isLastSection: {
|
isLastSection: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -146,7 +145,7 @@ const _fields = computed(() => {
|
|||||||
if (df?.depends_on) evaluate_depends_on(df.depends_on, field)
|
if (df?.depends_on) evaluate_depends_on(df.depends_on, field)
|
||||||
all_fields.push({
|
all_fields.push({
|
||||||
...field,
|
...field,
|
||||||
filters: df.link_filters && JSON.parse(df.link_filters),
|
filters: df?.link_filters && JSON.parse(df.link_filters),
|
||||||
placeholder: field.placeholder || field.label,
|
placeholder: field.placeholder || field.label,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -40,12 +40,12 @@
|
|||||||
v-for="(section, i) in sections.data"
|
v-for="(section, i) in sections.data"
|
||||||
:key="section.label"
|
:key="section.label"
|
||||||
class="flex flex-col py-1.5 px-1"
|
class="flex flex-col py-1.5 px-1"
|
||||||
:class="{ 'border-b': i !== sections.data.length - 1 }"
|
:class="{ 'border-b': i !== sections.data?.length - 1 }"
|
||||||
>
|
>
|
||||||
<Section :is-opened="section.opened" :label="section.label">
|
<Section :is-opened="section.opened" :label="section.label">
|
||||||
<SectionFields
|
<SectionFields
|
||||||
:fields="section.fields"
|
:fields="section.fields"
|
||||||
:isLastSection="i == section.data.length - 1"
|
:isLastSection="i == section.data?.length - 1"
|
||||||
v-model="data"
|
v-model="data"
|
||||||
/>
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
|
|||||||
@ -1,17 +1,19 @@
|
|||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useDebounceFn, useStorage } from '@vueuse/core'
|
import { useDebounceFn, useStorage } from '@vueuse/core'
|
||||||
|
|
||||||
export function useActiveTabManager(tabs, storageKey) {
|
export function useActiveTabManager(tabs, storageKey) {
|
||||||
const activieTab = useStorage(storageKey, 'activity')
|
const activieTab = useStorage(storageKey, 'activity')
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const preserveLastVisitedTab = useDebounceFn((tabName) => {
|
const preserveLastVisitedTab = useDebounceFn((tabName) => {
|
||||||
activieTab.value = tabName.toLowerCase()
|
activieTab.value = tabName.toLowerCase()
|
||||||
}, 300)
|
}, 300)
|
||||||
|
|
||||||
function setActiveTabInUrl(tabName) {
|
function setActiveTabInUrl(tabName) {
|
||||||
window.location.hash = '#' + tabName.toLowerCase()
|
let hash = '#' + tabName.toLowerCase()
|
||||||
|
router.push({ ...route, hash })
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActiveTabFromUrl() {
|
function getActiveTabFromUrl() {
|
||||||
@ -46,7 +48,6 @@ export function useActiveTabManager(tabs, storageKey) {
|
|||||||
|
|
||||||
let lastVisitedTab = getActiveTabFromLocalStorage()
|
let lastVisitedTab = getActiveTabFromLocalStorage()
|
||||||
if (lastVisitedTab) {
|
if (lastVisitedTab) {
|
||||||
setActiveTabInUrl(lastVisitedTab)
|
|
||||||
return getTabIndex(lastVisitedTab)
|
return getTabIndex(lastVisitedTab)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -607,7 +607,7 @@ function contactOptions(contact) {
|
|||||||
options.push({
|
options.push({
|
||||||
label: __('Set as Primary Contact'),
|
label: __('Set as Primary Contact'),
|
||||||
icon: h(SuccessIcon, { class: 'h-4 w-4' }),
|
icon: h(SuccessIcon, { class: 'h-4 w-4' }),
|
||||||
onClick: () => setPrimaryContact(contact),
|
onClick: () => setPrimaryContact(contact.name),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -522,7 +522,7 @@ function contactOptions(contact) {
|
|||||||
options.push({
|
options.push({
|
||||||
label: __('Set as Primary Contact'),
|
label: __('Set as Primary Contact'),
|
||||||
icon: h(SuccessIcon, { class: 'h-4 w-4' }),
|
icon: h(SuccessIcon, { class: 'h-4 w-4' }),
|
||||||
onClick: () => setPrimaryContact(contact),
|
onClick: () => setPrimaryContact(contact.name),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -145,9 +145,14 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
if (to.name === 'Home' && isLoggedIn) {
|
if (to.name === 'Home' && isLoggedIn) {
|
||||||
next({ name: 'Leads' })
|
next({ name: 'Leads' })
|
||||||
} else if (!isLoggedIn) {
|
} else if (!isLoggedIn) {
|
||||||
window.location.href = "/login?redirect-to=/crm";
|
window.location.href = '/login?redirect-to=/crm'
|
||||||
} else if (to.matched.length === 0) {
|
} else if (to.matched.length === 0) {
|
||||||
next({ name: 'Invalid Page' })
|
next({ name: 'Invalid Page' })
|
||||||
|
} else if (['Deal', 'Lead'].includes(to.name) && !to.hash) {
|
||||||
|
let storageKey = to.name === 'Deal' ? 'lastDealTab' : 'lastLeadTab'
|
||||||
|
const activeTab = localStorage.getItem(storageKey) || 'activity'
|
||||||
|
const hash = '#' + activeTab
|
||||||
|
next({ ...to, hash })
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user