2 changed files with 242 additions and 0 deletions
@ -0,0 +1,124 @@ |
|||||
|
<template> |
||||
|
<div class="flex flex-nowrap py-2"> |
||||
|
<div ref="titleContainerRef" class="flex items-end text-subtitle2 text-no-wrap">{{ title }}</div> |
||||
|
<q-space /> |
||||
|
<div ref="actionContainerRef" class="flex flex-nowrap"> |
||||
|
<!-- baseActions --> |
||||
|
<template v-for="(action, index) in baseActions" :key="'baseAction_' + index"> |
||||
|
<q-separator |
||||
|
v-if="action.separator" |
||||
|
vertical |
||||
|
class="class-action-item" |
||||
|
:style="{ |
||||
|
'margin-left': '5px', |
||||
|
'margin-right': '5px', |
||||
|
}" |
||||
|
/> |
||||
|
<q-btn |
||||
|
v-else |
||||
|
v-bind="action" |
||||
|
:id="action.name" |
||||
|
:disable="action.enableIf ? !action.enableIf() : false" |
||||
|
no-wrap |
||||
|
class="class-action-item" |
||||
|
:style="{ |
||||
|
'margin-left': '5px', |
||||
|
'margin-right': '5px', |
||||
|
}" |
||||
|
@click="action.click" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<!-- moreActions --> |
||||
|
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" :label="$t('more')" class="class-action-item" style="margin-left: 5px"> |
||||
|
<q-list> |
||||
|
<template v-for="(action, index) in moreActions" :key="'moreAction_' + index"> |
||||
|
<q-separator v-if="action.separator" /> |
||||
|
<q-item v-else v-close-popup clickable @click="action.click"> |
||||
|
<q-item-section avatar style="min-width: 28px; padding-right: 0px"> |
||||
|
<q-icon :name="action.icon" size="20px" /> |
||||
|
</q-item-section> |
||||
|
<q-item-section> |
||||
|
<q-item-label :v-bind="action">{{ action.label }}</q-item-label> |
||||
|
</q-item-section> |
||||
|
</q-item> |
||||
|
</template> |
||||
|
</q-list> |
||||
|
</q-btn-dropdown> |
||||
|
</div> |
||||
|
<q-resize-observer @resize="onResize" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { Tools } from '@/platform/utils'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
title: { type: String, default: '' }, |
||||
|
noActionIcon: { type: Boolean, default: false }, |
||||
|
actions: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const titleContainerRef = ref(); |
||||
|
const actionContainerRef = ref(); |
||||
|
|
||||
|
const actions = props.actions; |
||||
|
if (actions && actions.length > 0 && props.noActionIcon) { |
||||
|
for (const action of actions) { |
||||
|
action.icon = undefined; |
||||
|
} |
||||
|
} |
||||
|
const baseActions = ref(actions); |
||||
|
const moreActions = ref([]); |
||||
|
const isActionWidthInitializedRef = ref(false); |
||||
|
const moreActionWidth = 100; |
||||
|
|
||||
|
const onResize = (size) => { |
||||
|
if (Tools.isUndefinedOrNull(titleContainerRef.value) || Tools.isUndefinedOrNull(actionContainerRef.value)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!isActionWidthInitializedRef.value) { |
||||
|
const nodes = actionContainerRef.value.getElementsByClassName('class-action-item'); |
||||
|
for (let i = 0; i < actions.length; i++) { |
||||
|
actions[i].width = nodes[i].clientWidth + 10; |
||||
|
} |
||||
|
isActionWidthInitializedRef.value = true; |
||||
|
} |
||||
|
|
||||
|
const _baseActions = []; |
||||
|
const _moreActions = []; |
||||
|
const length = actions.length; |
||||
|
let availableWidth = size.width - titleContainerRef.value.clientWidth; |
||||
|
let width = 0; |
||||
|
let index = 0; |
||||
|
|
||||
|
for (; index < length; index++) { |
||||
|
console.log(index, width + actions[index].width, availableWidth); |
||||
|
if (width + actions[index].width > availableWidth) { |
||||
|
availableWidth -= moreActionWidth; |
||||
|
while (width > availableWidth) { |
||||
|
index--; |
||||
|
width -= actions[index].width; |
||||
|
_baseActions.pop(); |
||||
|
} |
||||
|
break; |
||||
|
} else { |
||||
|
_baseActions.push(actions[index]); |
||||
|
width += actions[index].width; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (; index < length; index++) { |
||||
|
_moreActions.push(actions[index]); |
||||
|
} |
||||
|
|
||||
|
baseActions.value = _baseActions; |
||||
|
moreActions.value = _moreActions; |
||||
|
}; |
||||
|
</script> |
@ -0,0 +1,118 @@ |
|||||
|
<template> |
||||
|
<div class="flex flex-nowrap py-2"> |
||||
|
<div ref="titleContainerRef" class="flex items-end text-subtitle2 text-no-wrap">{{ title }}</div> |
||||
|
<q-space /> |
||||
|
<div ref="actionContainerRef" class="flex flex-nowrap"> |
||||
|
<!-- baseActions --> |
||||
|
<template v-for="(action, index) in baseActions" :key="'baseAction_' + index"> |
||||
|
<q-separator |
||||
|
v-if="action.separator" |
||||
|
vertical |
||||
|
class="class-action-item" |
||||
|
:style="{ |
||||
|
'margin-left': '5px', |
||||
|
'margin-right': '5px', |
||||
|
}" |
||||
|
/> |
||||
|
<q-btn |
||||
|
v-else |
||||
|
v-bind="action" |
||||
|
:id="action.name" |
||||
|
:disable="action.enableIf ? !action.enableIf() : false" |
||||
|
no-wrap |
||||
|
class="class-action-item" |
||||
|
:style="{ |
||||
|
'margin-left': '5px', |
||||
|
'margin-right': '5px', |
||||
|
}" |
||||
|
@click="action.click" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<!-- moreActions --> |
||||
|
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" :label="$t('more')" class="class-action-item" style="margin-left: 5px"> |
||||
|
<q-list> |
||||
|
<template v-for="(action, index) in moreActions" :key="'moreAction_' + index"> |
||||
|
<q-separator v-if="action.separator" /> |
||||
|
<q-item v-else v-close-popup clickable @click="action.click"> |
||||
|
<q-item-section avatar style="min-width: 28px; padding-right: 0px"> |
||||
|
<q-icon :name="action.icon" size="20px" /> |
||||
|
</q-item-section> |
||||
|
<q-item-section> |
||||
|
<q-item-label :v-bind="action">{{ action.label }}</q-item-label> |
||||
|
</q-item-section> |
||||
|
</q-item> |
||||
|
</template> |
||||
|
</q-list> |
||||
|
</q-btn-dropdown> |
||||
|
</div> |
||||
|
<q-resize-observer @resize="onResize" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { Tools } from '@/platform/utils'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
title: { type: String, default: '' }, |
||||
|
actions: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const titleContainerRef = ref(); |
||||
|
const actionContainerRef = ref(); |
||||
|
|
||||
|
const actions = props.actions; |
||||
|
const baseActions = ref(actions); |
||||
|
const moreActions = ref([]); |
||||
|
const isActionWidthInitializedRef = ref(false); |
||||
|
const moreActionWidth = 100; |
||||
|
|
||||
|
const onResize = (size) => { |
||||
|
if (Tools.isUndefinedOrNull(titleContainerRef.value) || Tools.isUndefinedOrNull(actionContainerRef.value)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!isActionWidthInitializedRef.value) { |
||||
|
const nodes = actionContainerRef.value.getElementsByClassName('class-action-item'); |
||||
|
for (let i = 0; i < actions.length; i++) { |
||||
|
actions[i].width = nodes[i].clientWidth + 10; |
||||
|
} |
||||
|
isActionWidthInitializedRef.value = true; |
||||
|
} |
||||
|
|
||||
|
const _baseActions = []; |
||||
|
const _moreActions = []; |
||||
|
const length = actions.length; |
||||
|
let availableWidth = size.width - titleContainerRef.value.clientWidth; |
||||
|
let width = 0; |
||||
|
let index = 0; |
||||
|
|
||||
|
for (; index < length; index++) { |
||||
|
console.log(index, width + actions[index].width, availableWidth); |
||||
|
if (width + actions[index].width > availableWidth) { |
||||
|
availableWidth -= moreActionWidth; |
||||
|
while (width > availableWidth) { |
||||
|
index--; |
||||
|
width -= actions[index].width; |
||||
|
_baseActions.pop(); |
||||
|
} |
||||
|
break; |
||||
|
} else { |
||||
|
_baseActions.push(actions[index]); |
||||
|
width += actions[index].width; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (; index < length; index++) { |
||||
|
_moreActions.push(actions[index]); |
||||
|
} |
||||
|
|
||||
|
baseActions.value = _baseActions; |
||||
|
moreActions.value = _moreActions; |
||||
|
}; |
||||
|
</script> |
Loading…
Reference in new issue