seitime-frappe/frappe/public/js/print_format_builder/PrintFormatSection.vue
2022-10-05 15:41:14 +05:30

232 lines
4.9 KiB
Vue

<template>
<div class="print-format-section-container" v-if="!section.remove">
<div class="print-format-section">
<div class="section-header">
<input
class="input-section-label w-50"
type="text"
:placeholder="__('Section Title')"
v-model="section.label"
/>
<div class="d-flex align-items-center">
<div
class="mr-2 text-small text-muted d-flex"
v-if="section.field_orientation == 'left-right'"
:title="
// prettier-ignore
__('Render labels to the left and values to the right in this section')
"
>
Label Value
</div>
<div class="dropdown">
<button
class="btn btn-xs btn-section dropdown-button"
data-toggle="dropdown"
>
<svg class="icon icon-sm">
<use href="#icon-dot-horizontal"></use>
</svg>
</button>
<div
class="dropdown-menu dropdown-menu-right"
role="menu"
>
<button
v-for="option in section_options"
class="dropdown-item"
@click="option.action"
>
{{ option.label }}
</button>
</div>
</div>
</div>
</div>
<div class="row section-columns">
<div
class="column col"
v-for="(column, i) in section.columns"
:key="i"
>
<draggable
class="drag-container"
:style="{
backgroundColor: column.fields.length
? null
: 'var(--gray-50)'
}"
v-model="column.fields"
group="fields"
:animation="150"
item-key="id"
>
<template #item="{ element }">
<Field :df="element" />
</template>
</draggable>
</div>
</div>
</div>
<div
class="my-4 text-center text-muted font-italic"
v-if="section.page_break"
>
{{ __("Page Break") }}
</div>
</div>
</template>
<script setup>
import draggable from "vuedraggable";
import Field from "./Field.vue";
import { computed } from "vue";
// props
let props = defineProps(["section"]);
// emits
let emit = defineEmits(["add_section_above"]);
// methods
function add_column() {
if (props.section.columns.length < 4) {
props.section.columns.push({
label: "",
fields: []
});
}
}
function remove_column() {
if (props.section.columns.length <= 1) return;
let columns = props.section.columns.slice();
let last_column_fields = columns.slice(-1)[0].fields.slice();
let index = columns.length - 1;
columns = columns.slice(0, index);
let last_column = columns[index - 1];
last_column.fields = [...last_column.fields, ...last_column_fields];
props.section["columns"] = columns;
}
function add_page_break() {
props.section["page_break"] = true;
}
function remove_page_break() {
props.section["page_break"] = false;
}
// computed
let section_options = computed(() => {
return [
{
label: __("Add section above"),
action: () => emit("add_section_above")
},
{
label: __("Add column"),
action: add_column,
condition: () => props.section.columns.length < 4
},
{
label: __("Remove column"),
action: remove_column,
condition: () => props.section.columns.length > 1
},
{
label: __("Add page break"),
action: add_page_break,
condition: () => !props.section.page_break
},
{
label: __("Remove page break"),
action: remove_page_break,
condition: () => props.section.page_break
},
{
label: __("Remove section"),
action: () => { props.section["remove"] = true }
},
{
label: __("Field Orientation (Left-Right)"),
condition: () => !props.section.field_orientation,
action: () => { props.section["field_orientation"] = "left-right" }
},
{
label: __("Field Orientation (Top-Down)"),
condition: () =>
props.section.field_orientation == "left-right",
action: () => { props.section["field_orientation"] = "" }
}
].filter(option => (option.condition ? option.condition() : true));
})
</script>
<style scoped>
.print-format-section-container:not(:last-child) {
margin-bottom: 1rem;
}
.print-format-section {
background-color: white;
border: 1px solid var(--dark-border-color);
border-radius: var(--border-radius);
padding: 1rem;
cursor: pointer;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 0.75rem;
}
.input-section-label {
border: 1px solid transparent;
border-radius: var(--border-radius);
font-size: var(--text-md);
font-weight: 600;
}
.input-section-label:focus {
border-color: var(--border-color);
outline: none;
background-color: var(--control-bg);
}
.input-section-label::placeholder {
font-style: italic;
font-weight: normal;
}
.btn-section {
padding: var(--padding-xs);
box-shadow: none;
}
.btn-section:hover {
background-color: var(--bg-light-gray);
}
.print-format-section:not(:first-child) {
margin-top: 1rem;
}
.section-columns {
margin-left: -8px;
margin-right: -8px;
}
.column {
padding-left: 8px;
padding-right: 8px;
}
.drag-container {
height: 100%;
min-height: 2rem;
border-radius: var(--border-radius);
}
</style>