mirror of
https://github.com/frappe/books.git
synced 2024-12-22 19:09:01 +00:00
feat(ui/ux): add QuickView to AutoComplete
This commit is contained in:
parent
32ca9e1c32
commit
e05ef41cec
@ -41,6 +41,26 @@ export function isPesa(value: unknown): value is Money {
|
|||||||
return value instanceof Money;
|
return value instanceof Money;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isFalsy(value: unknown): boolean {
|
||||||
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPesa(value) && value.isZero()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'object' && Object.keys(value).length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export function getActions(doc: Doc): Action[] {
|
export function getActions(doc: Doc): Action[] {
|
||||||
const Model = doc.fyo.models[doc.schemaName];
|
const Model = doc.fyo.models[doc.schemaName];
|
||||||
if (Model === undefined) {
|
if (Model === undefined) {
|
||||||
|
@ -54,14 +54,22 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="canLink"
|
v-if="canLink"
|
||||||
class="p-0.5 rounded -me1 bg-transparent"
|
class="p-0.5 rounded -me1 bg-transparent"
|
||||||
|
@mouseenter="showQuickView = true"
|
||||||
|
@mouseleave="showQuickView = false"
|
||||||
@click="routeToLinkedDoc"
|
@click="routeToLinkedDoc"
|
||||||
>
|
>
|
||||||
<FeatherIcon name="chevron-right" class="w-4 h-4 text-gray-600" />
|
<feather-icon name="chevron-right" class="w-4 h-4 text-gray-600" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<Popover v-if="canLink" :show-popup="showQuickView" placement="bottom">
|
||||||
|
<template #content>
|
||||||
|
<QuickView :schema-name="linkSchemaName" :name="value" />
|
||||||
|
</template>
|
||||||
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
@ -71,7 +79,9 @@ import { FieldTypeEnum } from 'schemas/types';
|
|||||||
import Dropdown from 'src/components/Dropdown.vue';
|
import Dropdown from 'src/components/Dropdown.vue';
|
||||||
import { fuzzyMatch } from 'src/utils';
|
import { fuzzyMatch } from 'src/utils';
|
||||||
import { getFormRoute, routeTo } from 'src/utils/ui';
|
import { getFormRoute, routeTo } from 'src/utils/ui';
|
||||||
|
import Popover from '../Popover.vue';
|
||||||
import Base from './Base.vue';
|
import Base from './Base.vue';
|
||||||
|
import QuickView from '../QuickView.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AutoComplete',
|
name: 'AutoComplete',
|
||||||
@ -79,9 +89,12 @@ export default {
|
|||||||
extends: Base,
|
extends: Base,
|
||||||
components: {
|
components: {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
|
Popover,
|
||||||
|
QuickView,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
showQuickView: false,
|
||||||
linkValue: '',
|
linkValue: '',
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
@ -100,7 +113,23 @@ export default {
|
|||||||
const value = this.linkValue || this.value;
|
const value = this.linkValue || this.value;
|
||||||
this.setLinkValue(this.getLinkValue(value));
|
this.setLinkValue(this.getLinkValue(value));
|
||||||
},
|
},
|
||||||
|
unmounted() {
|
||||||
|
this.showQuickView = false;
|
||||||
|
},
|
||||||
|
deactivated() {
|
||||||
|
this.showQuickView = false;
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
linkSchemaName() {
|
||||||
|
let schemaName = this.df?.target;
|
||||||
|
|
||||||
|
if (!schemaName) {
|
||||||
|
const references = this.df?.references ?? '';
|
||||||
|
schemaName = this.doc?.[references];
|
||||||
|
}
|
||||||
|
|
||||||
|
return schemaName;
|
||||||
|
},
|
||||||
options() {
|
options() {
|
||||||
if (!this.df) {
|
if (!this.df) {
|
||||||
return [];
|
return [];
|
||||||
@ -139,19 +168,12 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async routeToLinkedDoc() {
|
async routeToLinkedDoc() {
|
||||||
let schemaName = this.df?.target;
|
|
||||||
const name = this.value;
|
const name = this.value;
|
||||||
|
if (!this.linkSchemaName || !name) {
|
||||||
if (!schemaName) {
|
|
||||||
const references = this.df?.references ?? '';
|
|
||||||
schemaName = this.doc?.[references];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!schemaName || !name) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = getFormRoute(schemaName, name);
|
const route = getFormRoute(this.linkSchemaName, name);
|
||||||
await routeTo(route);
|
await routeTo(route);
|
||||||
},
|
},
|
||||||
setLinkValue(value) {
|
setLinkValue(value) {
|
||||||
|
70
src/components/QuickView.vue
Normal file
70
src/components/QuickView.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<div style="min-width: 192px; max-width: 300px">
|
||||||
|
<div
|
||||||
|
class="p-2 flex justify-between"
|
||||||
|
:class="values.length ? 'border-b' : ''"
|
||||||
|
>
|
||||||
|
<p class="font-semibold text-base text-gray-900">{{ name }}</p>
|
||||||
|
<p class="font-semibold text-sm text-gray-600">
|
||||||
|
{{ schema?.label ?? '' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div v-if="values.length" class="flex gap-2 p-2 flex-wrap">
|
||||||
|
<p v-for="v of values" :key="v.label" class="pill bg-gray-200">
|
||||||
|
<span class="text-gray-600">{{ v.label }}</span>
|
||||||
|
<span class="text-gray-800 ml-1.5">{{ v.value }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { isFalsy } from 'fyo/utils';
|
||||||
|
import { Field } from 'schemas/types';
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
schemaName: { type: String, required: true },
|
||||||
|
name: { type: String, required: true },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { values: [] } as { values: { label: string; value: string }[] };
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
const fields: Field[] = (this.schema?.fields ?? []).filter(
|
||||||
|
(f) =>
|
||||||
|
f &&
|
||||||
|
f.fieldtype !== 'Table' &&
|
||||||
|
f.fieldtype !== 'AttachImage' &&
|
||||||
|
f.fieldtype !== 'Attachment' &&
|
||||||
|
f.fieldname !== 'name' &&
|
||||||
|
!f.hidden &&
|
||||||
|
!f.meta &&
|
||||||
|
!f.abstract
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = (
|
||||||
|
await this.fyo.db.getAll(this.schemaName, {
|
||||||
|
fields: fields.map((f) => f.fieldname),
|
||||||
|
filters: { name: this.name },
|
||||||
|
})
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
this.values = fields
|
||||||
|
.map((f) => {
|
||||||
|
const value = data[f.fieldname];
|
||||||
|
if (isFalsy(value)) {
|
||||||
|
return { value: '', label: '' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { value: this.fyo.format(data[f.fieldname], f), label: f.label };
|
||||||
|
})
|
||||||
|
.filter((i) => !!i.value);
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
schema() {
|
||||||
|
return this.fyo.schemaMap[this.schemaName];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user