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

This commit is contained in:
Shariq Ansari 2025-09-17 13:01:49 +05:30
parent 129f8a00b6
commit ac34ac9b87
5 changed files with 46 additions and 136 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,7 +169,7 @@
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'
import { TemplateOption, DropdownOption } from '@/utils' import { DropdownOption } from '@/utils'
import { import {
Dropdown, Dropdown,
Avatar, Avatar,
@ -216,29 +216,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,
}, },
] ]
@ -250,38 +240,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))