1
0
forked from test/crm

refactor: remove TemplateOption component usage and simplify dropdown options in multiple components

(cherry picked from commit ac34ac9b87b9c671be75401a545e09e0e83ac378)

# Conflicts:
#	frontend/src/components/Settings/Users.vue
This commit is contained in:
Shariq Ansari 2025-09-17 13:01:49 +05:30 committed by Mergify
parent 84d24a384b
commit ce4af4907a
5 changed files with 58 additions and 135 deletions

View File

@ -110,7 +110,6 @@
</template> </template>
<script setup> <script setup>
import { TemplateOption } from '@/utils'
import { import {
Autocomplete, Autocomplete,
Button, Button,
@ -191,31 +190,17 @@ const dropdownOptions = computed(() => {
options.push({ options.push({
label: __('Remove'), label: __('Remove'),
component: (props) => icon: 'trash-2',
TemplateOption({ variant: 'red',
option: __('Remove'), onClick: () => emit('remove'),
icon: 'trash-2',
active: props.active,
variant: 'danger',
onClick: () => {
emit('remove')
},
}),
condition: () => !props.isGroup, condition: () => !props.isGroup,
}) })
options.push({ options.push({
label: __('Remove group'), label: __('Remove group'),
component: (props) => icon: 'trash-2',
TemplateOption({ variant: 'red',
option: __('Remove group'), onClick: () => emit('remove'),
icon: 'trash-2',
active: props.active,
variant: 'danger',
onClick: () => {
emit('remove')
},
}),
condition: () => props.isGroup, condition: () => props.isGroup,
}) })

View File

@ -72,7 +72,6 @@ import {
toast, toast,
} from 'frappe-ui' } from 'frappe-ui'
import { inject, ref } from 'vue' import { inject, ref } from 'vue'
import { TemplateOption } from '@/utils'
const assignmentRulesList = inject('assignmentRulesList') const assignmentRulesList = inject('assignmentRulesList')
const updateStep = inject('updateStep') const updateStep = inject('updateStep')
@ -128,29 +127,19 @@ const dropdownOptions = [
}, },
{ {
label: __('Delete'), label: __('Delete'),
component: (props) => icon: 'trash-2',
TemplateOption({ onClick: (e) => {
option: __('Delete'), e.preventDefault()
icon: 'trash-2', e.stopImmediatePropagation()
active: props.active, isConfirmingDelete.value = true
onClick: (e) => { },
e.preventDefault()
e.stopImmediatePropagation()
isConfirmingDelete.value = true
},
}),
condition: () => !isConfirmingDelete.value, condition: () => !isConfirmingDelete.value,
}, },
{ {
label: __('Confirm Delete'), label: __('Confirm Delete'),
component: (props) => icon: 'trash-2',
TemplateOption({ theme: 'red',
option: __('Confirm Delete'), onClick: () => deleteAssignmentRule(),
icon: 'trash-2',
active: props.active,
theme: 'danger',
onClick: () => deleteAssignmentRule(),
}),
condition: () => isConfirmingDelete.value, condition: () => isConfirmingDelete.value,
}, },
] ]

View File

@ -148,7 +148,6 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { TemplateOption } from '@/utils'
import { import {
TextInput, TextInput,
FormControl, FormControl,
@ -223,43 +222,28 @@ function getDropdownOptions(template) {
let options = [ let options = [
{ {
label: __('Duplicate'), label: __('Duplicate'),
component: (props) => icon: 'copy',
TemplateOption({ onClick: () => emit('updateStep', 'new-template', { ...template }),
option: __('Duplicate'),
icon: 'copy',
active: props.active,
onClick: () => emit('updateStep', 'new-template', { ...template }),
}),
}, },
{ {
label: __('Delete'), label: __('Delete'),
component: (props) => icon: 'trash-2',
TemplateOption({ onClick: (e) => {
option: __('Delete'), e.preventDefault()
icon: 'trash-2', e.stopPropagation()
active: props.active, confirmDelete.value = true
onClick: (e) => { },
e.preventDefault()
e.stopPropagation()
confirmDelete.value = true
},
}),
condition: () => !confirmDelete.value, condition: () => !confirmDelete.value,
}, },
{ {
label: __('Confirm Delete'), label: __('Confirm Delete'),
component: (props) => icon: 'trash-2',
TemplateOption({ theme: 'red',
option: __('Confirm Delete'), onClick: () => deleteTemplate(template),
icon: 'trash-2',
active: props.active,
theme: 'danger',
onClick: () => deleteTemplate(template),
}),
condition: () => confirmDelete.value, condition: () => confirmDelete.value,
}, },
] ]
return options.filter((option) => option.condition?.() || true) return options
} }
</script> </script>

View File

@ -169,8 +169,21 @@
import AddExistingUserModal from '@/components/Modals/AddExistingUserModal.vue' import AddExistingUserModal from '@/components/Modals/AddExistingUserModal.vue'
import { activeSettingsPage } from '@/composables/settings' import { activeSettingsPage } from '@/composables/settings'
import { usersStore } from '@/stores/users' import { usersStore } from '@/stores/users'
<<<<<<< HEAD
import { TemplateOption, DropdownOption } from '@/utils' import { TemplateOption, DropdownOption } from '@/utils'
import { Avatar, TextInput, toast, call, FeatherIcon, Tooltip } from 'frappe-ui' import { Avatar, TextInput, toast, call, FeatherIcon, Tooltip } from 'frappe-ui'
=======
import { DropdownOption } from '@/utils'
import {
Dropdown,
Avatar,
TextInput,
toast,
call,
FeatherIcon,
Tooltip,
} from 'frappe-ui'
>>>>>>> ac34ac9b (refactor: remove TemplateOption component usage and simplify dropdown options in multiple components)
import { ref, computed, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'
const { users, isAdmin, isManager } = usersStore() const { users, isAdmin, isManager } = usersStore()
@ -208,29 +221,19 @@ function getMoreOptions(user) {
let options = [ let options = [
{ {
label: __('Remove'), label: __('Remove'),
component: (props) => icon: 'trash-2',
TemplateOption({ onClick: (e) => {
option: __('Remove'), e.preventDefault()
icon: 'trash-2', e.stopPropagation()
active: props.active, confirmRemove.value = true
onClick: (e) => { },
e.preventDefault()
e.stopPropagation()
confirmRemove.value = true
},
}),
condition: () => !confirmRemove.value, condition: () => !confirmRemove.value,
}, },
{ {
label: __('Confirm Remove'), label: __('Confirm Remove'),
component: (props) => icon: 'trash-2',
TemplateOption({ theme: 'red',
option: __('Confirm Remove'), onClick: () => removeUser(user, true),
icon: 'trash-2',
active: props.active,
theme: 'danger',
onClick: () => removeUser(user, true),
}),
condition: () => confirmRemove.value, condition: () => confirmRemove.value,
}, },
] ]
@ -242,38 +245,35 @@ function getDropdownOptions(user) {
let options = [ let options = [
{ {
label: __('Admin'), label: __('Admin'),
component: (props) => component: () =>
DropdownOption({ DropdownOption({
option: __('Admin'), option: __('Admin'),
icon: 'shield', icon: 'shield',
active: props.active,
selected: user.role === 'System Manager', selected: user.role === 'System Manager',
onClick: () => updateRole(user, 'System Manager'),
}), }),
onClick: () => updateRole(user, 'System Manager'),
condition: () => isAdmin(), condition: () => isAdmin(),
}, },
{ {
label: __('Manager'), label: __('Manager'),
component: (props) => component: () =>
DropdownOption({ DropdownOption({
option: __('Manager'), option: __('Manager'),
icon: 'briefcase', icon: 'briefcase',
active: props.active,
selected: user.role === 'Sales Manager', selected: user.role === 'Sales Manager',
onClick: () => updateRole(user, 'Sales Manager'),
}), }),
onClick: () => updateRole(user, 'Sales Manager'),
condition: () => isManager(), condition: () => isManager(),
}, },
{ {
label: __('Sales User'), label: __('Sales User'),
component: (props) => component: () =>
DropdownOption({ DropdownOption({
option: __('Sales User'), option: __('Sales User'),
icon: 'user-check', icon: 'user-check',
active: props.active,
selected: user.role === 'Sales User', selected: user.role === 'Sales User',
onClick: () => updateRole(user, 'Sales User'),
}), }),
onClick: () => updateRole(user, 'Sales User'),
}, },
] ]

View File

@ -462,23 +462,12 @@ export function runSequentially(functions) {
}, Promise.resolve()) }, Promise.resolve())
} }
export function DropdownOption({ export function DropdownOption({ option, icon, selected }) {
active,
option,
theme,
icon,
onClick,
selected,
}) {
return h( return h(
'button', 'button',
{ {
class: [ class:
active ? 'bg-surface-gray-2' : 'text-ink-gray-8', 'group flex w-full text-ink-gray-8 justify-between items-center rounded-md px-2 py-2 text-sm hover:bg-surface-gray-2',
'group flex w-full justify-between items-center rounded-md px-2 py-2 text-sm',
theme == 'danger' ? 'text-ink-red-3 hover:bg-ink-red-1' : '',
],
onClick: !selected ? onClick : null,
}, },
[ [
h('div', { class: 'flex gap-2' }, [ h('div', { class: 'flex gap-2' }, [
@ -501,30 +490,6 @@ export function DropdownOption({
) )
} }
export function TemplateOption({ active, option, theme, icon, onClick }) {
return h(
'button',
{
class: [
active ? 'bg-surface-gray-2 text-ink-gray-8' : 'text-ink-gray-7',
'group flex w-full gap-2 items-center rounded-md px-2 py-2 text-sm',
theme == 'danger' ? 'text-ink-red-3 hover:bg-ink-red-1' : '',
],
onClick: onClick,
},
[
icon
? h(FeatherIcon, {
name: icon,
class: ['h-4 w-4 shrink-0'],
'aria-hidden': true,
})
: null,
h('span', { class: 'whitespace-nowrap' }, option),
],
)
}
export function copy(obj) { export function copy(obj) {
if (!obj) return obj if (!obj) return obj
return JSON.parse(JSON.stringify(obj)) return JSON.parse(JSON.stringify(obj))