feat: separate component for each fieldtypes used in properties & main form

Worked on Data & Check Component. Components are created for each fieldtypes but each is still rendering Data Components template
This commit is contained in:
Shariq Ansari 2022-11-13 01:43:50 +05:30
parent 5a7839d8c8
commit 1c4f60ecd1
48 changed files with 2683 additions and 125 deletions

View file

@ -96,9 +96,7 @@ function move_columns_to_section() {
</div>
<draggable
class="column-container"
:style="{
backgroundColor: column.fields.length ? null : 'var(--gray-50)'
}"
:style="{ backgroundColor: column.fields.length ? '' : 'var(--gray-50)' }"
v-model="column.fields"
group="fields"
filter="[data-is-custom='0']"

View file

@ -1,5 +1,5 @@
<script setup>
import { ref, nextTick, computed, onMounted } from "vue";
import { ref, nextTick, computed } from "vue";
import { useStore } from "../store";
let store = useStore();

View file

@ -1,6 +1,5 @@
<script setup>
import EditableInput from "./EditableInput.vue";
import { ref, nextTick } from "vue";
import { ref } from "vue";
import { useStore } from "../store";
import { move_children_to_parent } from "../utils";
@ -34,58 +33,39 @@ function move_fields_to_column() {
store.selected(field.df.name) ? 'selected' : ''
]"
:title="field.df.fieldname"
@click.stop="store.selected_field = field.df;"
@click.stop="store.selected_field = field.df"
@mouseover.stop="hovered = true"
@mouseout.stop="hovered = false"
>
<div class="field-controls">
<EditableInput
:class="{ 'reqd': field.df.reqd }"
:text="field.df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${field.df.fieldtype})`"
v-model="field.df.label"
/>
<div class="field-actions" :hidden="store.read_only">
<button
v-if="field.df.fieldtype == 'HTML'"
class="btn btn-xs btn-icon"
@click="edit_html"
>
<div v-html="frappe.utils.icon('edit', 'sm')"></div>
</button>
<button
v-if="column.fields.indexOf(field)"
class="btn btn-xs btn-icon"
:title="__('Move the current field and the following fields to a new column')"
@click="move_fields_to_column"
>
<div
:style="{ strokeWidth: 0.6 }"
v-html="frappe.utils.icon('arrow-up-right', 'sm')"
></div>
</button>
<button class="btn btn-xs btn-icon" @click="remove_field">
<div v-html="frappe.utils.icon('close', 'sm')"></div>
</button>
</div>
</div>
<div
v-if="field.df.fieldtype == 'Table'"
class="table-controls row no-gutters"
:style="{ opacity: 1 }"
>
<div
class="table-column"
:style="{ width: tf.width + '%' }"
v-for="tf in field.table_columns"
:key="tf.fieldname"
>
<div class="table-field">
{{ tf.label }}
<component :is="field.df.fieldtype.replace(' ', '') + 'Control'" :df="field.df">
<template #actions>
<div class="field-actions" :hidden="store.read_only">
<button
v-if="field.df.fieldtype == 'HTML'"
class="btn btn-xs btn-icon"
@click="edit_html"
>
<div v-html="frappe.utils.icon('edit', 'sm')"></div>
</button>
<button
v-if="column.fields.indexOf(field)"
class="btn btn-xs btn-icon"
:title="
__('Move the current field and the following fields to a new column')
"
@click="move_fields_to_column"
>
<div
:style="{ strokeWidth: 0.6 }"
v-html="frappe.utils.icon('arrow-up-right', 'sm')"
></div>
</button>
<button class="btn btn-xs btn-icon" @click="remove_field">
<div v-html="frappe.utils.icon('close', 'sm')"></div>
</button>
</div>
</div>
</div>
</template>
</component>
</div>
</template>
@ -94,13 +74,13 @@ function move_fields_to_column() {
text-align: left;
width: 100%;
background-color: var(--bg-light-gray);
border-radius: var(--border-radius);
border: 1px solid var(--gray-400);
padding: 0.5rem 0.75rem;
border-radius: var(--border-radius-sm);
border: 1px solid transparent;
padding: 0.3rem;
font-size: var(--text-sm);
&:not(:first-child) {
margin-top: 0.5rem;
margin-top: 0.4rem;
}
&.hovered,
@ -111,25 +91,11 @@ function move_fields_to_column() {
}
}
.field-controls {
:deep(.field-controls) {
display: flex;
justify-content: space-between;
align-items: center;
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-input {
background-color: transparent;
border: none;
padding: 0;
&:focus {
outline: none;
}
}
margin-bottom: 0.3rem;
.field-actions {
flex: none;
@ -145,27 +111,5 @@ function move_fields_to_column() {
}
}
}
.table-controls {
display: flex;
margin-top: 1rem;
.table-column {
position: relative;
.table-field {
text-align: left;
width: 100%;
background-color: white;
border-radius: var(--border-radius);
border: 1px dashed var(--gray-400);
padding: 0.5rem 0.75rem;
font-size: var(--text-sm);
user-select: none;
white-space: nowrap;
overflow: hidden;
}
}
}
}
</style>

View file

@ -10,10 +10,7 @@ let search_text = ref("");
let docfield_df = computed(() => {
let fields = store.get_docfields.filter(df => {
if (
in_list(frappe.model.layout_fields, df.fieldtype) ||
df.hidden
) {
if (in_list(frappe.model.layout_fields, df.fieldtype) || df.hidden) {
return false;
}
if (df.depends_on && !evaluate_depends_on_value(df.depends_on, store.selected_field)) {
@ -41,16 +38,12 @@ let docfield_df = computed(() => {
<div class="control-data">
<div v-if="store.selected_field">
<div class="field" v-for="(df, i) in docfield_df" :key="i">
<div class="label">{{ df.label }}</div>
<div class="input">
<input
class="mb-2 form-control form-control-sm"
type="text"
v-model="store.selected_field[df.fieldname]"
:disabled="store.read_only || df.read_only"
/>
</div>
<div class="description" v-if="df.description">{{ df.description }}</div>
<component
:is="df.fieldtype.replace(' ', '') + 'Control'"
:df="df"
:value="store.selected_field[df.fieldname]"
v-model="store.selected_field[df.fieldname]"
/>
</div>
</div>
</div>
@ -66,15 +59,6 @@ let docfield_df = computed(() => {
margin: 5px;
margin-top: 0;
margin-bottom: 1rem;
.label {
margin-bottom: 0.3rem;
}
.description {
font-size: var(--text-sm);
color: var(--text-muted);
}
}
}
</style>

View file

@ -38,6 +38,14 @@ let fields = computed(() => {
return [...fields];
});
function on_drag_start(evt) {
$(evt.item).html('<div class="drag-it-here"></div>');
}
function on_drag_end(evt) {
let old_html = evt.clone.innerHTML;
$(evt.item).html(old_html);
}
</script>
<template>
@ -49,6 +57,9 @@ let fields = computed(() => {
:sort="false"
:clone="clone_field"
item-key="id"
:remove-clone-on-hide="false"
@start="on_drag_start"
@end="on_drag_end"
>
<template #item="{ element }">
<div class="field" :title="element.df.fieldtype">
@ -69,12 +80,18 @@ let fields = computed(() => {
grid-auto-rows: max-content;
.field {
display: block !important;
background-color: var(--bg-light-gray);
border-radius: var(--border-radius);
border: 0.5px solid var(--gray-400);
padding: 0.5rem 0.75rem;
font-size: var(--text-sm);
cursor: pointer;
&.sortable-ghost {
position: absolute;
opacity: 0;
}
}
}
</style>

View file

@ -70,14 +70,57 @@ onMounted(() => store.fetch());
:deep(.column-container .field.sortable-chosen) {
background-color: var(--bg-light-gray);
border-radius: var(--border-radius);
border: 1px solid var(--gray-400);
padding: 0.5rem 0.75rem;
border-radius: var(--border-radius-sm);
border: 1px solid transparent;
padding: 0.3rem;
font-size: var(--text-sm);
cursor: pointer;
&:has(.drag-it-here) {
position: relative;
background-color: transparent;
height: 60px;
.drag-it-here {
display: flex;
justify-content: center;
&::after {
content: "Drag it here";
top: 31%;
position: absolute;
padding: 2px 10px;
color: var(--fg-color);
background-color: var(--gray-500);
border-radius: var(--border-radius-full);
z-index: 1;
}
&::before {
content: "";
top: 47%;
position: absolute;
width: 97%;
height: 4px;
background-color: var(--gray-500);
border-radius: var(--border-radius-full);
}
}
}
&:not(:first-child) {
margin-top: 0.5rem;
margin-top: 0.4rem;
}
}
:deep(.field) {
.description {
font-size: var(--text-sm);
color: var(--text-muted);
}
.reqd::after {
content: " *";
color: var(--red-400);
}
}

View file

@ -3,7 +3,7 @@
<template>
<div class="search-box">
<input
class="search-input form-control form-control-sm"
class="search-input form-control"
type="text"
:placeholder="__('Search fields')"
@input="event => $emit('update:modelValue', event.target.value)"
@ -29,7 +29,7 @@
.search-icon {
position: absolute;
left: 16px;
top: 3px;
top: 5px;
}
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,60 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control checkbox">
<label>
<input
type="checkbox"
:checked="value"
:disabled="store.read_only || df.read_only"
@change="event => $emit('update:modelValue', event.target.checked)"
/>
<span class="label-area" :class="{ reqd: df.reqd }">{{ df.label }}</span>
</label>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control checkbox editable" v-else>
<label class="field-controls">
<div class="checkbox">
<input type="checkbox" disabled />
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
</div>
<slot name="actions"></slot>
</label>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
label, input {
margin-bottom: 0 !important;
cursor: pointer;
}
label .checkbox {
display: flex;
align-items: center;
input {
background-color: var(--fg-color);
box-shadow: none;
border: 1px solid var(--gray-400);
pointer-events: none;
}
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,59 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label" :class="{ reqd: df.reqd }">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label" :class="{ reqd: df.reqd }">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -0,0 +1,64 @@
<script setup>
import EditableInput from "../EditableInput.vue";
import { useStore } from "../../store";
import { useSlots } from "vue";
let store = useStore();
let props = defineProps(["df", "value"]);
let slots = useSlots();
</script>
<template>
<div v-if="!slots.actions" class="control">
<div class="label">{{ df.label }}</div>
<input
class="form-control"
type="text"
:value="value"
:disabled="store.read_only || df.read_only"
@input="event => $emit('update:modelValue', event.target.value)"
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
<div class="control editable" v-else>
<div class="field-controls">
<EditableInput
:class="{ reqd: df.reqd }"
:text="df.label"
:placeholder="__('Label')"
:empty_label="`${__('No Label')} (${df.fieldtype})`"
v-model="df.label"
/>
<slot name="actions"></slot>
</div>
<input
class="form-control"
type="text"
disabled
/>
<div v-if="df.description" class="mt-2 description" v-html="df.description"></div>
</div>
</template>
<style lang="scss" scoped>
.label {
margin-bottom: 0.3rem;
}
.editable input {
background-color: var(--fg-color);
cursor: pointer;
}
.reqd::after {
content: " *";
color: var(--red-400);
}
.label-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View file

@ -3,6 +3,7 @@ import { createPinia } from "pinia";
import { useStore } from "./store";
import FormBuilderComponent from "./components/FormBuilder.vue";
import { default as onOutsideClickDirective } from "./directives/onOutsideClick.js";
import { registerGlobalComponents } from "./globals.js";
class FormBuilder {
constructor({ wrapper, page, doctype, customize }) {
@ -65,6 +66,9 @@ class FormBuilder {
this.store.doctype = this.doctype;
this.store.is_customize_form = this.customize;
// register global components
registerGlobalComponents(app);
// directive
app.directive("on-outside-click", onOutsideClickDirective);

View file

@ -0,0 +1,81 @@
import AttachControl from "./components/controls/AttachControl.vue";
import AttachImageControl from "./components/controls/AttachImageControl.vue";
import AutocompleteControl from "./components/controls/AutocompleteControl.vue";
import BarcodeControl from "./components/controls/BarcodeControl.vue";
import ButtonControl from "./components/controls/ButtonControl.vue";
import CheckControl from "./components/controls/CheckControl.vue";
import CodeControl from "./components/controls/CodeControl.vue";
import ColorControl from "./components/controls/ColorControl.vue";
import CurrencyControl from "./components/controls/CurrencyControl.vue";
import DataControl from "./components/controls/DataControl.vue";
import DateControl from "./components/controls/DateControl.vue";
import DatetimeControl from "./components/controls/DatetimeControl.vue";
import DurationControl from "./components/controls/DurationControl.vue";
import DynamicLinkControl from "./components/controls/DynamicLinkControl.vue";
import FloatControl from "./components/controls/FloatControl.vue";
import GeolocationControl from "./components/controls/GeolocationControl.vue";
import HeadingControl from "./components/controls/HeadingControl.vue";
import HTMLControl from "./components/controls/HTMLControl.vue";
import HTMLEditorControl from "./components/controls/HTMLEditorControl.vue";
import IconControl from "./components/controls/IconControl.vue";
import ImageControl from "./components/controls/ImageControl.vue";
import IntControl from "./components/controls/IntControl.vue";
import JSONControl from "./components/controls/JSONControl.vue";
import LinkControl from "./components/controls/LinkControl.vue";
import LongTextControl from "./components/controls/LongTextControl.vue";
import MarkdownEditorControl from "./components/controls/MarkdownEditorControl.vue";
import PasswordControl from "./components/controls/PasswordControl.vue";
import PercentControl from "./components/controls/PercentControl.vue";
import PhoneControl from "./components/controls/PhoneControl.vue";
import ReadOnlyControl from "./components/controls/ReadOnlyControl.vue";
import RatingControl from "./components/controls/RatingControl.vue";
import SelectControl from "./components/controls/SelectControl.vue";
import SignatureControl from "./components/controls/SignatureControl.vue";
import SmallTextControl from "./components/controls/SmallTextControl.vue";
import TableControl from "./components/controls/TableControl.vue";
import TableMultiSelectControl from "./components/controls/TableMultiSelectControl.vue";
import TextControl from "./components/controls/TextControl.vue";
import TextEditorControl from "./components/controls/TextEditorControl.vue";
import TimeControl from "./components/controls/TimeControl.vue";
export function registerGlobalComponents(app) {
app.component("AttachControl", AttachControl)
.component("AttachImageControl", AttachImageControl)
.component("AutocompleteControl", AutocompleteControl)
.component("BarcodeControl", BarcodeControl)
.component("ButtonControl", ButtonControl)
.component("CheckControl", CheckControl)
.component("CodeControl", CodeControl)
.component("ColorControl", ColorControl)
.component("CurrencyControl", CurrencyControl)
.component("DataControl", DataControl)
.component("DateControl", DateControl)
.component("DatetimeControl", DatetimeControl)
.component("DurationControl", DurationControl)
.component("DynamicLinkControl", DynamicLinkControl)
.component("FloatControl", FloatControl)
.component("GeolocationControl", GeolocationControl)
.component("HeadingControl", HeadingControl)
.component("HTMLControl", HTMLControl)
.component("HTMLEditorControl", HTMLEditorControl)
.component("IconControl", IconControl)
.component("ImageControl", ImageControl)
.component("IntControl", IntControl)
.component("JSONControl", JSONControl)
.component("LinkControl", LinkControl)
.component("LongTextControl", LongTextControl)
.component("MarkdownEditorControl", MarkdownEditorControl)
.component("PasswordControl", PasswordControl)
.component("PercentControl", PercentControl)
.component("PhoneControl", PhoneControl)
.component("ReadOnlyControl", ReadOnlyControl)
.component("RatingControl", RatingControl)
.component("SelectControl", SelectControl)
.component("SignatureControl", SignatureControl)
.component("SmallTextControl", SmallTextControl)
.component("TableControl", TableControl)
.component("TableMultiSelectControl", TableMultiSelectControl)
.component("TextControl", TextControl)
.component("TextEditorControl", TextEditorControl)
.component("TimeControl", TimeControl);
}