Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf849f7dff | ||
|
|
3e9fdb8d20 | ||
|
|
260755fd2e | ||
|
|
85df56b464 | ||
|
|
a9e956b5fc | ||
|
|
905eb63c5f | ||
|
|
3eee437014 | ||
|
|
4498de2041 | ||
|
|
bfb0d25765 | ||
|
|
9dd6ffa1e1 | ||
|
|
05322e805f | ||
|
|
8dc6db3218 | ||
|
|
1b63384eac | ||
|
|
37bbbb6b4b | ||
|
|
6f0244c2b6 | ||
|
|
e08bc9cd20 | ||
|
|
2043157567 | ||
|
|
8093a422cd | ||
|
|
4bef919d38 | ||
|
|
874947b8ae | ||
|
|
ca90c0406e | ||
|
|
6bf27d852b | ||
|
|
793cb76789 | ||
|
|
ff07054ca3 | ||
|
|
2ee5269d3e | ||
|
|
e27954da52 | ||
|
|
2faa0d0f04 | ||
|
|
f1664eec2f | ||
|
|
7f2efea7cb | ||
|
|
d2cc6b7c2e | ||
|
|
1afb6d6827 | ||
|
|
ccaf136830 | ||
|
|
58a41d1b11 | ||
|
|
777f3ac06c | ||
|
|
105c78e264 | ||
|
|
46cc1d2924 | ||
|
|
ff4ca9fe66 | ||
|
|
4989dc0921 | ||
|
|
1e613ebcd1 |
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
__version__ = "1.53.0"
|
__version__ = "1.53.1"
|
||||||
__title__ = "Frappe CRM"
|
__title__ = "Frappe CRM"
|
||||||
|
|
||||||
|
|||||||
137
crm/api/doc.py
137
crm/api/doc.py
@ -750,7 +750,11 @@ def getCounts(d, doctype):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_linked_docs_of_document(doctype, docname):
|
def get_linked_docs_of_document(doctype, docname):
|
||||||
doc = frappe.get_doc(doctype, docname)
|
try:
|
||||||
|
doc = frappe.get_doc(doctype, docname)
|
||||||
|
except frappe.DoesNotExistError:
|
||||||
|
return []
|
||||||
|
|
||||||
linked_docs = get_linked_docs(doc)
|
linked_docs = get_linked_docs(doc)
|
||||||
dynamic_linked_docs = get_dynamic_linked_docs(doc)
|
dynamic_linked_docs = get_dynamic_linked_docs(doc)
|
||||||
|
|
||||||
@ -759,7 +763,14 @@ def get_linked_docs_of_document(doctype, docname):
|
|||||||
|
|
||||||
docs_data = []
|
docs_data = []
|
||||||
for doc in linked_docs:
|
for doc in linked_docs:
|
||||||
data = frappe.get_doc(doc["reference_doctype"], doc["reference_docname"])
|
if not doc.get("reference_doctype") or not doc.get("reference_docname"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = frappe.get_doc(doc["reference_doctype"], doc["reference_docname"])
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
continue
|
||||||
|
|
||||||
title = data.get("title")
|
title = data.get("title")
|
||||||
if data.doctype == "CRM Call Log":
|
if data.doctype == "CRM Call Log":
|
||||||
title = f"Call from {data.get('from')} to {data.get('to')}"
|
title = f"Call from {data.get('from')} to {data.get('to')}"
|
||||||
@ -767,6 +778,9 @@ def get_linked_docs_of_document(doctype, docname):
|
|||||||
if data.doctype == "CRM Deal":
|
if data.doctype == "CRM Deal":
|
||||||
title = data.get("organization")
|
title = data.get("organization")
|
||||||
|
|
||||||
|
if data.doctype == "CRM Notification":
|
||||||
|
title = data.get("message")
|
||||||
|
|
||||||
docs_data.append(
|
docs_data.append(
|
||||||
{
|
{
|
||||||
"doc": data.doctype,
|
"doc": data.doctype,
|
||||||
@ -779,25 +793,51 @@ def get_linked_docs_of_document(doctype, docname):
|
|||||||
|
|
||||||
|
|
||||||
def remove_doc_link(doctype, docname):
|
def remove_doc_link(doctype, docname):
|
||||||
linked_doc_data = frappe.get_doc(doctype, docname)
|
if not doctype or not docname:
|
||||||
linked_doc_data.update(
|
return
|
||||||
{
|
|
||||||
"reference_doctype": None,
|
try:
|
||||||
"reference_docname": None,
|
linked_doc_data = frappe.get_doc(doctype, docname)
|
||||||
}
|
if doctype == "CRM Notification":
|
||||||
)
|
delete_notification_type = {
|
||||||
linked_doc_data.save(ignore_permissions=True)
|
"notification_type_doctype": "",
|
||||||
|
"notification_type_doc": "",
|
||||||
|
}
|
||||||
|
delete_references = {
|
||||||
|
"reference_doctype": "",
|
||||||
|
"reference_name": "",
|
||||||
|
}
|
||||||
|
if linked_doc_data.get("notification_type_doctype") == linked_doc_data.get("reference_doctype"):
|
||||||
|
delete_references.update(delete_notification_type)
|
||||||
|
|
||||||
|
linked_doc_data.update(delete_references)
|
||||||
|
else:
|
||||||
|
linked_doc_data.update(
|
||||||
|
{
|
||||||
|
"reference_doctype": "",
|
||||||
|
"reference_docname": "",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
linked_doc_data.save(ignore_permissions=True)
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def remove_contact_link(doctype, docname):
|
def remove_contact_link(doctype, docname):
|
||||||
linked_doc_data = frappe.get_doc(doctype, docname)
|
if not doctype or not docname:
|
||||||
linked_doc_data.update(
|
return
|
||||||
{
|
|
||||||
"contact": None,
|
try:
|
||||||
"contacts": [],
|
linked_doc_data = frappe.get_doc(doctype, docname)
|
||||||
}
|
linked_doc_data.update(
|
||||||
)
|
{
|
||||||
linked_doc_data.save(ignore_permissions=True)
|
"contact": None,
|
||||||
|
"contacts": [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
linked_doc_data.save(ignore_permissions=True)
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -806,13 +846,19 @@ def remove_linked_doc_reference(items, remove_contact=None, delete=False):
|
|||||||
items = frappe.parse_json(items)
|
items = frappe.parse_json(items)
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
if remove_contact:
|
if not item.get("doctype") or not item.get("docname"):
|
||||||
remove_contact_link(item["doctype"], item["docname"])
|
continue
|
||||||
else:
|
|
||||||
remove_doc_link(item["doctype"], item["docname"])
|
|
||||||
|
|
||||||
if delete:
|
try:
|
||||||
frappe.delete_doc(item["doctype"], item["docname"])
|
if remove_contact:
|
||||||
|
remove_contact_link(item["doctype"], item["docname"])
|
||||||
|
else:
|
||||||
|
remove_doc_link(item["doctype"], item["docname"])
|
||||||
|
if delete:
|
||||||
|
frappe.delete_doc(item["doctype"], item["docname"])
|
||||||
|
except (frappe.DoesNotExistError, frappe.ValidationError):
|
||||||
|
# Skip if document doesn't exist or has validation errors
|
||||||
|
continue
|
||||||
|
|
||||||
return "success"
|
return "success"
|
||||||
|
|
||||||
@ -821,19 +867,40 @@ def remove_linked_doc_reference(items, remove_contact=None, delete=False):
|
|||||||
def delete_bulk_docs(doctype, items, delete_linked=False):
|
def delete_bulk_docs(doctype, items, delete_linked=False):
|
||||||
from frappe.desk.reportview import delete_bulk
|
from frappe.desk.reportview import delete_bulk
|
||||||
|
|
||||||
|
if not doctype:
|
||||||
|
frappe.throw("Doctype is required")
|
||||||
|
|
||||||
|
if not items:
|
||||||
|
frappe.throw("Items are required")
|
||||||
|
|
||||||
items = frappe.parse_json(items)
|
items = frappe.parse_json(items)
|
||||||
|
if not isinstance(items, list):
|
||||||
|
frappe.throw("Items must be a list")
|
||||||
|
|
||||||
for doc in items:
|
for doc in items:
|
||||||
linked_docs = get_linked_docs_of_document(doctype, doc)
|
try:
|
||||||
for linked_doc in linked_docs:
|
if not frappe.db.exists(doctype, doc):
|
||||||
remove_linked_doc_reference(
|
frappe.log_error(f"Document {doctype} {doc} does not exist", "Bulk Delete Error")
|
||||||
[
|
continue
|
||||||
{
|
|
||||||
"doctype": linked_doc["reference_doctype"],
|
linked_docs = get_linked_docs_of_document(doctype, doc)
|
||||||
"docname": linked_doc["reference_docname"],
|
for linked_doc in linked_docs:
|
||||||
}
|
if not linked_doc.get("reference_doctype") or not linked_doc.get("reference_docname"):
|
||||||
],
|
continue
|
||||||
remove_contact=doctype == "Contact",
|
|
||||||
delete=delete_linked,
|
remove_linked_doc_reference(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"doctype": linked_doc["reference_doctype"],
|
||||||
|
"docname": linked_doc["reference_docname"],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
remove_contact=doctype == "Contact",
|
||||||
|
delete=delete_linked,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
frappe.log_error(
|
||||||
|
f"Error processing linked docs for {doctype} {doc}: {str(e)}", "Bulk Delete Error"
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(items) > 10:
|
if len(items) > 10:
|
||||||
|
|||||||
543
crm/locale/ar.po
543
crm/locale/ar.po
File diff suppressed because it is too large
Load Diff
549
crm/locale/bs.po
549
crm/locale/bs.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/cs.po
543
crm/locale/cs.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/da.po
543
crm/locale/da.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/de.po
543
crm/locale/de.po
File diff suppressed because it is too large
Load Diff
549
crm/locale/eo.po
549
crm/locale/eo.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/es.po
543
crm/locale/es.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/fa.po
543
crm/locale/fa.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/fr.po
543
crm/locale/fr.po
File diff suppressed because it is too large
Load Diff
549
crm/locale/hr.po
549
crm/locale/hr.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/hu.po
543
crm/locale/hu.po
File diff suppressed because it is too large
Load Diff
545
crm/locale/id.po
545
crm/locale/id.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/it.po
543
crm/locale/it.po
File diff suppressed because it is too large
Load Diff
577
crm/locale/nb.po
577
crm/locale/nb.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/nl.po
543
crm/locale/nl.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/pl.po
543
crm/locale/pl.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/pt.po
543
crm/locale/pt.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
543
crm/locale/ru.po
543
crm/locale/ru.po
File diff suppressed because it is too large
Load Diff
549
crm/locale/sr.po
549
crm/locale/sr.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
549
crm/locale/sv.po
549
crm/locale/sv.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/th.po
543
crm/locale/th.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/tr.po
543
crm/locale/tr.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/vi.po
543
crm/locale/vi.po
File diff suppressed because it is too large
Load Diff
543
crm/locale/zh.po
543
crm/locale/zh.po
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@
|
|||||||
"@tiptap/extension-paragraph": "^2.12.0",
|
"@tiptap/extension-paragraph": "^2.12.0",
|
||||||
"@twilio/voice-sdk": "^2.10.2",
|
"@twilio/voice-sdk": "^2.10.2",
|
||||||
"@vueuse/integrations": "^10.3.0",
|
"@vueuse/integrations": "^10.3.0",
|
||||||
"frappe-ui": "^0.1.200",
|
"frappe-ui": "^0.1.201",
|
||||||
"gemoji": "^8.1.0",
|
"gemoji": "^8.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mime": "^4.0.1",
|
"mime": "^4.0.1",
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-ink-gray-5">
|
<div class="text-ink-gray-5 text-base">
|
||||||
{{
|
{{
|
||||||
__('Are you sure you want to delete {0} items?', [
|
__('Are you sure you want to delete {0} items?', [
|
||||||
props.items?.length,
|
props.items?.length,
|
||||||
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-ink-gray-5">
|
<div class="text-ink-gray-5 text-base">
|
||||||
{{
|
{{
|
||||||
confirmDeleteInfo.delete
|
confirmDeleteInfo.delete
|
||||||
? __(
|
? __(
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<Dialog v-model="show" :options="{ size: 'xl' }">
|
<Dialog v-model="show" :options="{ size: 'xl' }">
|
||||||
<template #body v-if="!confirmDeleteInfo.show">
|
<template #body v-if="!confirmDeleteInfo.show">
|
||||||
<div class="bg-surface-modal px-4 pb-6 pt-5 sm:px-6">
|
<div class="bg-surface-modal px-4 pb-6 pt-5 sm:px-6">
|
||||||
<div class="mb-4 flex items-center justify-between">
|
<div class="mb-6 flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-2xl leading-6 text-ink-gray-9 font-semibold">
|
<h3 class="text-2xl leading-6 text-ink-gray-9 font-semibold">
|
||||||
{{
|
{{
|
||||||
@ -32,11 +32,12 @@
|
|||||||
{
|
{
|
||||||
label: 'Document',
|
label: 'Document',
|
||||||
key: 'title',
|
key: 'title',
|
||||||
|
width: '19rem',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Master',
|
label: 'Master',
|
||||||
key: 'reference_doctype',
|
key: 'reference_doctype',
|
||||||
width: '30%',
|
width: '12rem',
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
@selectionsChanged="
|
@selectionsChanged="
|
||||||
|
|||||||
@ -26,13 +26,14 @@
|
|||||||
<ListRowItem
|
<ListRowItem
|
||||||
:item="item"
|
:item="item"
|
||||||
@click="listViewRef.toggleRow(row['reference_docname'])"
|
@click="listViewRef.toggleRow(row['reference_docname'])"
|
||||||
|
class="!w-full"
|
||||||
>
|
>
|
||||||
<template #default="{ label }">
|
<template #default="{ label }">
|
||||||
<div
|
<div
|
||||||
v-if="column.key === 'title'"
|
v-if="column.key === 'title'"
|
||||||
class="truncate text-base flex gap-2"
|
class="truncate text-base flex gap-2 w-full"
|
||||||
>
|
>
|
||||||
<span>
|
<span class="max-w-[90%] truncate">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</span>
|
</span>
|
||||||
<FeatherIcon
|
<FeatherIcon
|
||||||
@ -102,6 +103,7 @@ const listViewRef = ref(null)
|
|||||||
const viewLinkedDoc = (doc) => {
|
const viewLinkedDoc = (doc) => {
|
||||||
let page = ''
|
let page = ''
|
||||||
let id = ''
|
let id = ''
|
||||||
|
let openDesk = false
|
||||||
switch (doc.reference_doctype) {
|
switch (doc.reference_doctype) {
|
||||||
case 'CRM Lead':
|
case 'CRM Lead':
|
||||||
page = 'leads'
|
page = 'leads'
|
||||||
@ -123,6 +125,11 @@ const viewLinkedDoc = (doc) => {
|
|||||||
page = 'organizations'
|
page = 'organizations'
|
||||||
id = doc.reference_docname
|
id = doc.reference_docname
|
||||||
break
|
break
|
||||||
|
case 'CRM Notification':
|
||||||
|
page = 'crm-notification'
|
||||||
|
id = doc.reference_docname
|
||||||
|
openDesk = true
|
||||||
|
break
|
||||||
case 'FCRM Note':
|
case 'FCRM Note':
|
||||||
page = 'notes'
|
page = 'notes'
|
||||||
id = `view?open=${doc.reference_docname}`
|
id = `view?open=${doc.reference_docname}`
|
||||||
@ -130,7 +137,11 @@ const viewLinkedDoc = (doc) => {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
window.open(`/crm/${page}/${id}`)
|
let base = '/crm'
|
||||||
|
if (openDesk) {
|
||||||
|
base = '/app'
|
||||||
|
}
|
||||||
|
window.open(`${base}/${page}/${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDoctypeName = (doctype) => {
|
const getDoctypeName = (doctype) => {
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { getScript } from '@/data/script'
|
import { getScript } from '@/data/script'
|
||||||
import { globalStore } from '@/stores/global'
|
import { globalStore } from '@/stores/global'
|
||||||
|
import { getMeta } from '@/stores/meta'
|
||||||
import { showSettings, activeSettingsPage } from '@/composables/settings'
|
import { showSettings, activeSettingsPage } from '@/composables/settings'
|
||||||
import { runSequentially, parseAssignees } from '@/utils'
|
import { runSequentially, parseAssignees, evaluateExpression } from '@/utils'
|
||||||
import { createDocumentResource, createResource, toast } from 'frappe-ui'
|
import { createDocumentResource, createResource, toast } from 'frappe-ui'
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ const assigneesCache = {}
|
|||||||
|
|
||||||
export function useDocument(doctype, docname) {
|
export function useDocument(doctype, docname) {
|
||||||
const { setupScript, scripts } = getScript(doctype)
|
const { setupScript, scripts } = getScript(doctype)
|
||||||
|
const meta = getMeta(doctype)
|
||||||
|
|
||||||
documentsCache[doctype] = documentsCache[doctype] || {}
|
documentsCache[doctype] = documentsCache[doctype] || {}
|
||||||
|
|
||||||
@ -37,6 +39,7 @@ export function useDocument(doctype, docname) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setValue: {
|
setValue: {
|
||||||
|
validate,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
triggerOnSave()
|
triggerOnSave()
|
||||||
toast.success(__('Document updated successfully'))
|
toast.success(__('Document updated successfully'))
|
||||||
@ -152,6 +155,42 @@ export function useDocument(doctype, docname) {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validate(d) {
|
||||||
|
checkMandatory(d.doc || d.fieldname)
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkMandatory(doc) {
|
||||||
|
let fields = meta?.getFields() || []
|
||||||
|
|
||||||
|
if (!fields || fields.length === 0) return
|
||||||
|
|
||||||
|
let missingFields = []
|
||||||
|
|
||||||
|
fields.forEach((df) => {
|
||||||
|
let parent = meta?.doctypeMeta?.[df.parent] || null
|
||||||
|
if (evaluateExpression(df.mandatory_depends_on, doc, parent)) {
|
||||||
|
const value = doc[df.fieldname]
|
||||||
|
if (
|
||||||
|
value === undefined ||
|
||||||
|
value === null ||
|
||||||
|
(typeof value === 'string' && value.trim() === '') ||
|
||||||
|
(Array.isArray(value) && value.length === 0)
|
||||||
|
) {
|
||||||
|
missingFields.push(df.label || df.fieldname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (missingFields.length > 0) {
|
||||||
|
toast.error(
|
||||||
|
__('Mandatory fields required: {0}', [missingFields.join(', ')]),
|
||||||
|
)
|
||||||
|
throw new Error(
|
||||||
|
__('Mandatory fields required: {0}', [missingFields.join(', ')]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function triggerOnLoad() {
|
async function triggerOnLoad() {
|
||||||
const handler = async function () {
|
const handler = async function () {
|
||||||
await (this.onLoad?.() || this.on_load?.() || this.onload?.())
|
await (this.onLoad?.() || this.on_load?.() || this.onload?.())
|
||||||
@ -280,6 +319,7 @@ export function useDocument(doctype, docname) {
|
|||||||
assignees: assigneesCache[doctype][docname || ''],
|
assignees: assigneesCache[doctype][docname || ''],
|
||||||
scripts,
|
scripts,
|
||||||
error,
|
error,
|
||||||
|
validate,
|
||||||
getControllers,
|
getControllers,
|
||||||
triggerOnLoad,
|
triggerOnLoad,
|
||||||
triggerOnBeforeCreate,
|
triggerOnBeforeCreate,
|
||||||
|
|||||||
@ -421,6 +421,36 @@ export function evaluateDependsOnValue(expression, doc) {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function evaluateExpression(expression, doc, parent) {
|
||||||
|
if (!expression) return false
|
||||||
|
if (!doc) return false
|
||||||
|
|
||||||
|
let out = null
|
||||||
|
if (typeof expression === 'boolean') {
|
||||||
|
out = expression
|
||||||
|
} else if (typeof expression === 'function') {
|
||||||
|
out = expression(doc)
|
||||||
|
} else if (expression.substr(0, 5) == 'eval:') {
|
||||||
|
try {
|
||||||
|
out = _eval(expression.substr(5), { doc, parent })
|
||||||
|
if (parent && parent.istable && expression.includes('is_submittable')) {
|
||||||
|
out = true
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
out = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let value = doc[expression]
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
out = !!value.length
|
||||||
|
} else {
|
||||||
|
out = !!value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
export function convertSize(size) {
|
export function convertSize(size) {
|
||||||
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||||
let unitIndex = 0
|
let unitIndex = 0
|
||||||
|
|||||||
@ -2572,10 +2572,10 @@ fraction.js@^4.3.7:
|
|||||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
||||||
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
|
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
|
||||||
|
|
||||||
frappe-ui@^0.1.200:
|
frappe-ui@^0.1.201:
|
||||||
version "0.1.200"
|
version "0.1.201"
|
||||||
resolved "https://registry.yarnpkg.com/frappe-ui/-/frappe-ui-0.1.200.tgz#2cdaa24708f0dbe98b0dd6c2536b5974418fdfef"
|
resolved "https://registry.yarnpkg.com/frappe-ui/-/frappe-ui-0.1.201.tgz#12a18f08b97489facd4a170b4cbfc8adbbf1f109"
|
||||||
integrity sha512-mlkGS5oZxKYcpAit6qehjmoYqo6NvrWmSrbhvkpYDXecEBWU3IgJkMzt13753Z3QTbWbJv7y3iadlVge8u+FMw==
|
integrity sha512-kVz9K3W22ZuxGScSCct2kUFexZ1uZPM6FCc5BWAep3UcEzHRSbHzmLyEKCu0FKzftXtDHwNG8AoUDyHrDPkvCw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@floating-ui/vue" "^1.1.6"
|
"@floating-ui/vue" "^1.1.6"
|
||||||
"@headlessui/vue" "^1.7.14"
|
"@headlessui/vue" "^1.7.14"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user