* feat: add i18n * refactor/feat: workflow attributes type * refactor: workflow => gray stat card * refactor: select menu with search => separator * feat: workflow => workflow step properties * fix: workflow type * fix: dialog properties component => model data * fix: form flow => prevent toggle expansion with keyboard * refactor: workflow step data & change status * fix: form flow properties btn * refactor: side menu => hide sub index * feat: workflow => avatar & status on table * refactor: workflow => drawer id and dialog id * feat: workflow => card * fix: agencies => format address
112 lines
2.5 KiB
Vue
112 lines
2.5 KiB
Vue
<script lang="ts" setup>
|
|
import { ref } from 'vue';
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
readonly?: boolean;
|
|
|
|
title?: string;
|
|
width?: string;
|
|
offset?: number[];
|
|
|
|
option: Record<string, unknown>[];
|
|
optionLabel?: string;
|
|
separatorIndex?: number[];
|
|
}>(),
|
|
{
|
|
readonly: false,
|
|
option: () => [],
|
|
optionLabel: 'label',
|
|
offset: () => [0, 12],
|
|
separatorIndex: () => [],
|
|
},
|
|
);
|
|
|
|
const inputSearch = ref('');
|
|
|
|
defineEmits<{
|
|
(e: 'search', value: string | number | null): void;
|
|
(e: 'select', value: Record<string, unknown>): void;
|
|
(e: 'hide'): void;
|
|
(e: 'show'): void;
|
|
(e: 'beforeHide'): void;
|
|
(e: 'beforeShow'): void;
|
|
}>();
|
|
</script>
|
|
<template>
|
|
<q-menu
|
|
v-if="!readonly"
|
|
:offset
|
|
class="bordered"
|
|
:style="`width: ${width}`"
|
|
@show="$emit('show')"
|
|
@hide="$emit('hide')"
|
|
@before-show="
|
|
() => {
|
|
inputSearch = '';
|
|
$emit('beforeShow');
|
|
}
|
|
"
|
|
@before-hide="$emit('beforeHide')"
|
|
>
|
|
<div
|
|
v-if="title"
|
|
class="column no-padding"
|
|
style="padding: 16px !important"
|
|
>
|
|
<span class="text-weight-bold q-pb-sm">
|
|
{{ title }}
|
|
</span>
|
|
|
|
<q-input
|
|
for="input-search"
|
|
outlined
|
|
dense
|
|
:label="$t('general.search')"
|
|
class="col responsible-search"
|
|
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
|
|
v-model="inputSearch"
|
|
debounce="200"
|
|
@update:model-value="(val) => $emit('search', val)"
|
|
>
|
|
<template #prepend>
|
|
<q-icon name="mdi-magnify" />
|
|
</template>
|
|
</q-input>
|
|
</div>
|
|
|
|
<template v-if="$slots.prepend">
|
|
<slot name="prepend"></slot>
|
|
</template>
|
|
|
|
<span v-if="option.length === 0">
|
|
<q-item dense class="flex items-center app-text-muted">
|
|
{{ $t('general.noData') }}
|
|
</q-item>
|
|
</span>
|
|
<template v-if="option.length > 0">
|
|
<q-item
|
|
v-for="(opt, i) in option"
|
|
dense
|
|
:key="i"
|
|
class="flex items-center"
|
|
:class="{ 'bordered-t': separatorIndex.includes(i) }"
|
|
clickable
|
|
@click.stop="$emit('select', opt)"
|
|
>
|
|
<template v-if="$slots.option">
|
|
<slot name="option" :opt="opt"></slot>
|
|
</template>
|
|
|
|
<span v-if="!$slots.option" class="row items-center">
|
|
{{ opt.label }}
|
|
</span>
|
|
</q-item>
|
|
</template>
|
|
|
|
<template v-if="$slots.append">
|
|
<slot name="append"></slot>
|
|
</template>
|
|
</q-menu>
|
|
</template>
|
|
<style scoped></style>
|