Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Moved CRM Settings to Portal #496

Merged
merged 12 commits into from
Dec 30, 2024
Merged
27 changes: 12 additions & 15 deletions crm/fcrm/doctype/crm_fields_layout/crm_fields_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,13 @@ def get_fields_layout(doctype: str, type: str):
for field in section.get("fields") if section.get("fields") else []:
field = next((f for f in fields if f.fieldname == field), None)
if field:
if field.fieldtype == "Select" and field.options:
field.options = field.options.split("\n")
field.options = [{"label": _(option), "value": option} for option in field.options]
field.options.insert(0, {"label": "", "value": ""})
field = {
"label": _(field.label),
"name": field.fieldname,
"type": field.fieldtype,
"options": field.options,
"options": getOptions(field),
"mandatory": field.reqd,
"read_only": field.read_only,
"placeholder": field.get("placeholder"),
"filters": field.get("link_filters"),
}
Expand Down Expand Up @@ -86,17 +83,17 @@ def save_fields_layout(doctype: str, type: str, layout: str):
def get_default_layout(doctype: str):
fields = frappe.get_meta(doctype).fields
fields = [
{
"label": _(field.label),
"name": field.fieldname,
"type": field.fieldtype,
"options": field.options,
"mandatory": field.reqd,
"placeholder": field.get("placeholder"),
"filters": field.get("link_filters"),
}
field.fieldname
for field in fields
if field.fieldtype not in ["Section Break", "Column Break"]
if field.fieldtype not in ["Tab Break", "Section Break", "Column Break"]
]

return [{"no_tabs": True, "sections": [{"hideLabel": True, "fields": fields}]}]


def getOptions(field):
if field.fieldtype == "Select" and field.options:
field.options = field.options.split("\n")
field.options = [{"label": _(option), "value": option} for option in field.options]
field.options.insert(0, {"label": "", "value": ""})
return field.options
41 changes: 30 additions & 11 deletions frontend/src/components/Controls/Grid.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="flex flex-col text-base">
<div class="flex flex-col flex-1 text-base">
<div v-if="label" class="mb-1.5 text-sm text-ink-gray-5">
{{ __(label) }}
</div>
Expand Down Expand Up @@ -55,9 +55,16 @@
<template #item="{ element: row, index }">
<div
class="grid-row flex cursor-pointer items-center border-b border-outline-gray-modals bg-surface-modals last:rounded-b last:border-b-0"
@click.stop="
() => {
if (!gridSettings.editable_grid) {
showRowList[index] = true
}
}
"
>
<div
class="inline-flex h-9.5 items-center justify-center border-r border-outline-gray-modals p-2 w-12"
class="grid-row-checkbox inline-flex h-9.5 items-center bg-surface-white justify-center border-r border-outline-gray-modals p-2 w-12"
>
<Checkbox
class="cursor-pointer duration-300"
Expand All @@ -66,7 +73,7 @@
/>
</div>
<div
class="flex h-9.5 items-center justify-center border-r border-outline-gray-modals py-2 px-1 text-sm text-ink-gray-8 w-12"
class="flex h-9.5 items-center justify-center bg-surface-white border-r border-outline-gray-modals py-2 px-1 text-sm text-ink-gray-8 w-12"
>
{{ index + 1 }}
</div>
Expand All @@ -88,11 +95,12 @@
/>
<div
v-else-if="field.type === 'Check'"
class="flex h-full justify-center items-center"
class="flex h-full bg-surface-white justify-center items-center"
>
<Checkbox
class="cursor-pointer duration-300"
v-model="row[field.name]"
:disabled="!gridSettings.editable_grid"
/>
</div>
<DatePicker
Expand Down Expand Up @@ -233,7 +241,10 @@ const props = defineProps({
},
})

const { getGridSettings, getFields } = getMeta(props.doctype)
const { getGridViewSettings, getFields, getGridSettings } = getMeta(
props.doctype,
)
getMeta(props.parentDoctype)

const rows = defineModel()
const showRowList = ref(new Array(rows.value?.length || []).fill(false))
Expand All @@ -242,11 +253,13 @@ const selectedRows = reactive(new Set())
const showGridFieldsEditorModal = ref(false)
const showGridRowFieldsModal = ref(false)

const gridSettings = computed(() => getGridSettings())

const fields = computed(() => {
let gridSettings = getGridSettings(props.parentDoctype)
let gridViewSettings = getGridViewSettings(props.parentDoctype)
let gridFields = getFields()
if (gridSettings.length) {
let d = gridSettings.map((gs) =>
if (gridViewSettings.length) {
let d = gridViewSettings.map((gs) =>
getFieldObj(gridFields.find((f) => f.fieldname === gs.fieldname)),
)
return d
Expand All @@ -269,9 +282,11 @@ function getFieldObj(field) {
const gridTemplateColumns = computed(() => {
if (!fields.value?.length) return '1fr'
// for the checkbox & sr no. columns
let gridSettings = getGridSettings(props.parentDoctype)
if (gridSettings.length) {
return gridSettings.map((gs) => `minmax(0, ${gs.columns || 2}fr)`).join(' ')
let gridViewSettings = getGridViewSettings(props.parentDoctype)
if (gridViewSettings.length) {
return gridViewSettings
.map((gs) => `minmax(0, ${gs.columns || 2}fr)`)
.join(' ')
}
return fields.value.map(() => `minmax(0, 2fr)`).join(' ')
})
Expand Down Expand Up @@ -353,6 +368,10 @@ const deleteRows = () => {
height: 38px;
}

:deep(.grid-row:last-child .grid-row-checkbox) {
border-bottom-left-radius: 7px;
}

:deep(.grid-row .edit-row button) {
border-bottom-right-radius: 7px;
}
Expand Down
16 changes: 4 additions & 12 deletions frontend/src/components/Controls/GridFieldsEditorModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ const props = defineProps({
parentDoctype: String,
})

const { userSettings, getFields, getGridSettings, saveUserSettings } = getMeta(
const { getFields, getGridViewSettings, saveUserSettings } = getMeta(
props.doctype,
)

Expand All @@ -122,10 +122,10 @@ const dirty = computed(() => {

const oldFields = computed(() => {
let _fields = getFields()
let gridSettings = getGridSettings(props.parentDoctype)
let gridViewSettings = getGridViewSettings(props.parentDoctype)

if (gridSettings.length) {
return gridSettings.map((field) => {
if (gridViewSettings.length) {
return gridViewSettings.map((field) => {
let f = _fields.find((f) => f.fieldname === field.fieldname)
if (f) {
f.columns = field.columns
Expand Down Expand Up @@ -175,14 +175,6 @@ function update() {
saveUserSettings(props.parentDoctype, 'GridView', updateFields, () => {
loading.value = false
show.value = false
if (userSettings[props.parentDoctype]?.['GridView']) {
userSettings[props.parentDoctype]['GridView'][props.doctype] =
updateFields
} else {
userSettings[props.parentDoctype] = {
GridView: { [props.doctype]: updateFields },
}
}
})
}

Expand Down
23 changes: 1 addition & 22 deletions frontend/src/components/Controls/GridRowModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
<script setup>
import EditIcon from '@/components/Icons/EditIcon.vue'
import FieldLayout from '@/components/FieldLayout.vue'
import { getMeta } from '@/stores/meta'
import { usersStore } from '@/stores/users'
import { createResource } from 'frappe-ui'
import { nextTick } from 'vue'
Expand All @@ -44,36 +43,16 @@ const props = defineProps({
doctype: String,
})

const { getFields } = getMeta(props.doctype)
const { isManager } = usersStore()

const show = defineModel()
const showGridRowFieldsModal = defineModel('showGridRowFieldsModal')

const tabs = createResource({
url: 'crm.fcrm.doctype.crm_fields_layout.crm_fields_layout.get_fields_layout',
cache: ['GridRow', props.doctype],
cache: ['Grid Row', props.doctype],
params: { doctype: props.doctype, type: 'Grid Row' },
auto: true,
transform: (data) => {
if (data.length) return data
let fields = getFields()
if (!fields) return []
return [
{
no_tabs: true,
sections: [
{
hideLabel: true,
opened: true,
fields: fields.map((f) => {
return { ...f, name: f.fieldname, type: f.fieldtype }
}),
},
],
},
]
},
})

function openGridRowFieldsModal() {
Expand Down
42 changes: 42 additions & 0 deletions frontend/src/components/Controls/ImageUploader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<template>
<FileUploader
:file-types="image_type"
class="text-base"
@success="
(file) => {
$emit('upload', file.file_url)
}
"
>
<template v-slot="{ progress, uploading, openFileSelector }">
<div class="flex items-end space-x-1">
<Button @click="openFileSelector">
{{
uploading
? `Uploading ${progress}%`
: image_url
? 'Change'
: 'Upload'
}}
</Button>
<Button v-if="image_url" @click="$emit('remove')">Remove</Button>
</div>
</template>
</FileUploader>
</template>
<script setup>
import { FileUploader, Button } from 'frappe-ui'

const prop = defineProps({
image_url: String,
image_type: {
type: String,
default: 'image/*',
},
label: {
type: String,
default: '',
},
})
const emit = defineEmits(['upload', 'remove'])
</script>
39 changes: 26 additions & 13 deletions frontend/src/components/FieldLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<Tabs
v-model="tabIndex"
class="!h-full"
:tabs="tabs"
:tabs="_tabs"
v-slot="{ tab }"
:tablistClass="
!hasTabs ? 'hidden' : modal ? 'border-outline-gray-modals' : ''
Expand Down Expand Up @@ -44,16 +44,7 @@
]"
>
<div v-for="field in section.fields" :key="field.name">
<div
class="settings-field"
v-if="
(field.type == 'Check' ||
(field.read_only && data[field.name]) ||
!field.read_only ||
!field.hidden) &&
(!field.depends_on || field.display_via_depends_on)
"
>
<div class="settings-field">
<div
v-if="field.type != 'Check'"
class="mb-2 text-sm text-ink-gray-5"
Expand All @@ -79,7 +70,6 @@
<Grid
v-else-if="field.type === 'Table'"
v-model="data[field.name]"
:fields="field.fields"
:doctype="field.options"
:parentDoctype="doctype"
/>
Expand Down Expand Up @@ -109,7 +99,13 @@
/>
<label
class="text-sm text-ink-gray-5"
@click="data[field.name] = !data[field.name]"
@click="
() => {
if (!Boolean(field.read_only)) {
data[field.name] = !data[field.name]
}
}
"
>
{{ __(field.label) }}
<span class="text-ink-red-3" v-if="field.mandatory"
Expand Down Expand Up @@ -273,6 +269,23 @@ const { getUser } = usersStore()

const hasTabs = computed(() => !props.tabs[0].no_tabs)

const _tabs = computed(() => {
return props.tabs.map((tab) => {
tab.sections = tab.sections.map((section) => {
section.fields = section.fields.filter(
(field) =>
(field.type == 'Check' ||
(field.read_only && props.data[field.name]) ||
!field.read_only) &&
(!field.depends_on || field.display_via_depends_on) &&
!field.hidden,
)
return section
})
return tab
})
})

const tabIndex = ref(0)

function gridClass(columns) {
Expand Down
Loading
Loading