mirror of
https://github.com/frappe/books.git
synced 2025-01-24 07:38:25 +00:00
incr: add template key hint
- shift TemplateBuilder into folder
This commit is contained in:
parent
e33ca5c313
commit
dca5b52567
@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<PageHeader :title="t`Template Builder`">Hi</PageHeader>
|
<PageHeader :title="t`Template Builder`"
|
||||||
|
><Button v-if="displayDoc" @click="showHint = true">{{
|
||||||
|
t`Show Hint`
|
||||||
|
}}</Button></PageHeader
|
||||||
|
>
|
||||||
<!-- Template Builder Body -->
|
<!-- Template Builder Body -->
|
||||||
<div class="w-full h-full flex" v-if="doc">
|
<div class="w-full h-full flex" v-if="doc">
|
||||||
<!-- Print View Container -->
|
<!-- Print View Container -->
|
||||||
@ -116,13 +120,35 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Hint Modal -->
|
||||||
|
<Modal
|
||||||
|
@closemodal="() => (showHint = false)"
|
||||||
|
:open-modal="showHint"
|
||||||
|
v-if="displayDoc && hint"
|
||||||
|
>
|
||||||
|
<div class="w-form">
|
||||||
|
<!-- Hint Modal Header -->
|
||||||
|
<FormHeader
|
||||||
|
:form-title="t`Hint`"
|
||||||
|
:form-sub-title="displayDoc.schema.label"
|
||||||
|
/>
|
||||||
|
<hr />
|
||||||
|
<div class="p-4 max-h-96 overflow-auto custom-scroll">
|
||||||
|
<TemplateBuilderHint :hint="hint" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PrintTemplate } from 'models/baseModels/PrintTemplate';
|
import { PrintTemplate } from 'models/baseModels/PrintTemplate';
|
||||||
import { ModelNameEnum } from 'models/types';
|
import { ModelNameEnum } from 'models/types';
|
||||||
import { Field, TargetField } from 'schemas/types';
|
import { Field, TargetField } from 'schemas/types';
|
||||||
|
import Button from 'src/components/Button.vue';
|
||||||
import FormControl from 'src/components/Controls/FormControl.vue';
|
import FormControl from 'src/components/Controls/FormControl.vue';
|
||||||
|
import FormHeader from 'src/components/FormHeader.vue';
|
||||||
|
import Modal from 'src/components/Modal.vue';
|
||||||
import PageHeader from 'src/components/PageHeader.vue';
|
import PageHeader from 'src/components/PageHeader.vue';
|
||||||
import {
|
import {
|
||||||
getPrintTemplatePropHints,
|
getPrintTemplatePropHints,
|
||||||
@ -131,39 +157,61 @@ import {
|
|||||||
import { getDocFromNameIfExistsElseNew } from 'src/utils/ui';
|
import { getDocFromNameIfExistsElseNew } from 'src/utils/ui';
|
||||||
import { getMapFromList } from 'utils/index';
|
import { getMapFromList } from 'utils/index';
|
||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
|
import TemplateBuilderHint from './TemplateBuilderHint.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: { name: String },
|
props: { name: String },
|
||||||
components: { PageHeader, FormControl },
|
components: {
|
||||||
|
PageHeader,
|
||||||
|
FormControl,
|
||||||
|
Button,
|
||||||
|
Modal,
|
||||||
|
FormHeader,
|
||||||
|
TemplateBuilderHint,
|
||||||
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return { doc: computed(() => this.doc) };
|
return { doc: computed(() => this.doc) };
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
doc: null,
|
doc: null,
|
||||||
|
showHint: false,
|
||||||
|
hint: null,
|
||||||
|
values: null,
|
||||||
templateCollapsed: false,
|
templateCollapsed: false,
|
||||||
helpersCollapsed: true,
|
helpersCollapsed: true,
|
||||||
displayDoc: null,
|
displayDoc: null,
|
||||||
} as {
|
} as {
|
||||||
|
hint: null | Record<string, unknown>;
|
||||||
|
values: null | Record<string, unknown>;
|
||||||
doc: PrintTemplate | null;
|
doc: PrintTemplate | null;
|
||||||
|
showHint: boolean;
|
||||||
displayDoc: PrintTemplate | null;
|
displayDoc: PrintTemplate | null;
|
||||||
templateCollapsed: boolean;
|
templateCollapsed: boolean;
|
||||||
helpersCollapsed: boolean;
|
helpersCollapsed: boolean;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
// @ts-ignore
|
|
||||||
window.tb = this;
|
|
||||||
await this.setDoc();
|
await this.setDoc();
|
||||||
|
|
||||||
if (!this.doc?.template) {
|
if (!this.doc?.template) {
|
||||||
this.helpersCollapsed = false;
|
this.helpersCollapsed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.fyo.store.isDevelopment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
window.tb = this;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.hints = getPrintTemplatePropHints;
|
window.hints = getPrintTemplatePropHints;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.values = getPrintTemplatePropValues;
|
window.values = getPrintTemplatePropValues;
|
||||||
|
|
||||||
|
this.setDisplayDoc('SINV-1001');
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async setDoc() {
|
async setDoc() {
|
||||||
@ -178,6 +226,8 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
async setDisplayDoc(value: string) {
|
async setDisplayDoc(value: string) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
this.hint = null;
|
||||||
|
this.values = null;
|
||||||
this.displayDoc = null;
|
this.displayDoc = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -186,8 +236,10 @@ export default defineComponent({
|
|||||||
if (!schemaName) {
|
if (!schemaName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const displayDoc = await getDocFromNameIfExistsElseNew(schemaName, value);
|
||||||
this.displayDoc = await getDocFromNameIfExistsElseNew(schemaName, value);
|
this.hint = getPrintTemplatePropHints(displayDoc);
|
||||||
|
this.values = await getPrintTemplatePropValues(displayDoc);
|
||||||
|
this.displayDoc = displayDoc;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
110
src/pages/TemplateBuilder/TemplateBuilderHint.vue
Normal file
110
src/pages/TemplateBuilder/TemplateBuilderHint.vue
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="level > 0 ? 'ms-2 ps-2 border-l' : ''">
|
||||||
|
<template v-for="r of rows" :key="r.key">
|
||||||
|
<div
|
||||||
|
class="
|
||||||
|
flex
|
||||||
|
gap-2
|
||||||
|
text-sm text-gray-600
|
||||||
|
whitespace-nowrap
|
||||||
|
overflow-auto
|
||||||
|
no-scrollbar
|
||||||
|
"
|
||||||
|
:class="[typeof r.value === 'object' ? 'cursor-pointer' : '']"
|
||||||
|
@click="r.collapsed = !r.collapsed"
|
||||||
|
>
|
||||||
|
<div class="">{{ getKey(r) }}</div>
|
||||||
|
<div v-if="!r.isCollapsible" class="font-semibold text-gray-800">
|
||||||
|
{{ r.value }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="Array.isArray(r.value)"
|
||||||
|
class="
|
||||||
|
text-blue-600
|
||||||
|
bg-blue-50
|
||||||
|
border-blue-200 border
|
||||||
|
tracking-tighter
|
||||||
|
rounded
|
||||||
|
text-xs
|
||||||
|
px-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Array
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="
|
||||||
|
text-green-600
|
||||||
|
bg-green-50
|
||||||
|
border-green-200 border
|
||||||
|
tracking-tighter
|
||||||
|
rounded
|
||||||
|
text-xs
|
||||||
|
px-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Object
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<feather-icon
|
||||||
|
v-if="r.isCollapsible"
|
||||||
|
:name="r.collapsed ? 'chevron-up' : 'chevron-down'"
|
||||||
|
class="w-4 h-4 ms-auto"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-if="!r.collapsed && typeof r.value === 'object'">
|
||||||
|
<TemplateBuilderHint
|
||||||
|
:prefix="getKey(r)"
|
||||||
|
:hint="Array.isArray(r.value) ? r.value[0] : r.value"
|
||||||
|
:level="level + 1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
type HintRow = {
|
||||||
|
key: string;
|
||||||
|
value: string | Record<string, unknown>;
|
||||||
|
isCollapsible: boolean;
|
||||||
|
collapsed: boolean;
|
||||||
|
};
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'TemplateBuilderHint',
|
||||||
|
props: {
|
||||||
|
prefix: { type: String, default: '' },
|
||||||
|
hint: { type: Object, required: true },
|
||||||
|
level: { type: Number, default: 0 },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { rows: [] } as {
|
||||||
|
rows: HintRow[];
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.rows = Object.entries(this.hint)
|
||||||
|
.map(([key, value]) => ({
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
isCollapsible: typeof value === 'object',
|
||||||
|
collapsed: this.level > 0,
|
||||||
|
}))
|
||||||
|
.sort((a, b) => Number(a.isCollapsible) - Number(b.isCollapsible));
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getKey(row: HintRow) {
|
||||||
|
const isArray = Array.isArray(row.value);
|
||||||
|
if (isArray) {
|
||||||
|
return `${this.prefix}.${row.key}[number]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.prefix.length) {
|
||||||
|
return `${this.prefix}.${row.key}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return row.key;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@ -1,5 +1,5 @@
|
|||||||
import { ModelNameEnum } from 'models/types';
|
import { ModelNameEnum } from 'models/types';
|
||||||
import TemplateBuilder from 'src/pages/TemplateBuilder.vue';
|
import TemplateBuilder from 'src/pages/TemplateBuilder/TemplateBuilder.vue';
|
||||||
import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
|
import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
|
||||||
import CommonForm from 'src/pages/CommonForm/CommonForm.vue';
|
import CommonForm from 'src/pages/CommonForm/CommonForm.vue';
|
||||||
import Dashboard from 'src/pages/Dashboard/Dashboard.vue';
|
import Dashboard from 'src/pages/Dashboard/Dashboard.vue';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user