Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import VueformRenderer #1526

Merged
merged 10 commits into from
Feb 2, 2024
284 changes: 152 additions & 132 deletions src/components/editor/loop.vue
Original file line number Diff line number Diff line change
@@ -1,129 +1,145 @@
<template>
<div class="column-draggable" :selector="config.customCssSelector">
<draggable
style="min-height: 80px;"
:list="items"
group="controls"
>
<div class="control-item"
:class="{selected: selected === element, hasError: hasError(element)}"
v-for="(element,index) in items"
:key="index"
@click.stop="inspect(element)"
>
<div v-if="element.container" @click.stop="inspect(element)">
<div class="m-2 card border-0" :class="{ 'ai-section-card': isAiSection(element) && selected === element }">
<div
v-if="selected === element"
class="card-header form-element-header d-flex align-items-center border rounded"
:class="{ 'pulse': isAiSection(element) }"
>
<i class="fas fa-arrows-alt-v mr-1 text-muted"/>
<i v-if="element.config.icon" :class="element.config.icon" class="mr-2 ml-1"/>
{{ element.config.name || $t('Variable Name') }}
<div class="ml-auto">
<button
v-if="isAiSection(element) && aiPreview(element)"
class="btn btn-sm btn-primary mr-2"
:title="$t('Apply Changes')"
@click="applyAiChanges(element)"
>
{{ $t("Apply Changes") }}
</button>
<button
v-if="!(isAiSection(element) && aiPreview(element))"
class="btn btn-sm btn-secondary mr-2"
:title="$t('Copy Control')"
@click="duplicateItem(index)"
<draggable style="min-height: 80px" :list="items" group="controls">
<div
v-for="(element, index) in items"
:key="index"
class="control-item"
:class="{ selected: selected === element, hasError: hasError(element) }"
@click.stop="inspect(element)"
>
<div v-if="element.container" @click.stop="inspect(element)">
<div
class="m-2 card border-0"
:class="{
'ai-section-card': isAiSection(element) && selected === element
}"
>
<i class="fas fa-copy text-light"/>
</button>
<button
class="btn btn-sm btn-danger"
@click="deleteItem(index)"
:aria-label="$t('Delete')"
>
<i class="far fa-trash-alt text-light"/>
</button>
</div>
</div>

<component :class="elementCssClass(element)"
:validationErrors="validationErrors"
class="mb-3 mr-3 ml-3"
:selected="selected"
:ai-element="element"
@inspect="inspect"
@update-state="$emit('update-state')"
v-model="element.items"
:config="element.config"
:is="element['editor-component']"
/>
</div>
</div>
<div
v-if="selected === element"
class="card-header form-element-header d-flex align-items-center border rounded"
:class="{ pulse: isAiSection(element) }"
>
<i class="fas fa-arrows-alt-v mr-1 text-muted" />
<i
v-if="element.config.icon"
:class="element.config.icon"
class="mr-2 ml-1"
/>
{{ element.config.name || $t("Variable Name") }}
<div class="ml-auto">
<button
v-if="isAiSection(element) && aiPreview(element)"
class="btn btn-sm btn-primary mr-2"
:title="$t('Apply Changes')"
@click="applyAiChanges(element)"
>
{{ $t("Apply Changes") }}
</button>
<button
v-if="!(isAiSection(element) && aiPreview(element))"
class="btn btn-sm btn-secondary mr-2"
:title="$t('Copy Control')"
@click="duplicateItem(index)"
>
<i class="fas fa-copy text-light" />
</button>
<button
class="btn btn-sm btn-danger"
:aria-label="$t('Delete')"
@click="deleteItem(index)"
>
<i class="far fa-trash-alt text-light" />
</button>
</div>
</div>

<div v-else :id="element.config.name ? element.config.name : undefined">
<div class="m-2" :class="{ 'card' : selected === element }">
<div
v-if="selected === element"
class="card-header form-element-header d-flex align-items-center"
>
<i class="fas fa-arrows-alt-v mr-1 text-muted"/>
<i v-if="element.config.icon" :class="element.config.icon" class="mr-2 ml-1"/>
{{ element.config.name || $t('Variable Name') }}
<div class="ml-auto">
<button
class="btn btn-sm btn-secondary mr-2"
:title="$t('Copy Control')"
@click="duplicateItem(index)"
>
<i class="fas fa-copy text-light"/>
</button>
<button
class="btn btn-sm btn-danger"
@click="deleteItem(index)"
:aria-label="$t('Delete')"
>
<i class="far fa-trash-alt text-light"/>
</button>
</div>
</div>
<component
v-model="element.items"
:is="element['editor-component']"
:class="elementCssClass(element)"
:validation-errors="validationErrors"
class="mb-3 mr-3 ml-3"
:selected="selected"
:ai-element="element"
:config="element.config"
@inspect="inspect"
@update-state="$emit('update-state')"
/>
</div>
</div>

<div v-else :id="element.config.name ? element.config.name : undefined">
<div class="m-2" :class="{ card: selected === element }">
<div
v-if="selected === element"
class="card-header form-element-header d-flex align-items-center"
>
<i class="fas fa-arrows-alt-v mr-1 text-muted" />
<i
v-if="element.config.icon"
:class="element.config.icon"
class="mr-2 ml-1"
/>
{{ element.config.name || $t("Variable Name") }}
<div class="ml-auto">
<button
class="btn btn-sm btn-secondary mr-2"
:title="$t('Copy Control')"
@click="duplicateItem(index)"
>
<i class="fas fa-copy text-light" />
</button>
<button
class="btn btn-sm btn-danger"
:aria-label="$t('Delete')"
@click="deleteItem(index)"
>
<i class="far fa-trash-alt text-light" />
</button>
</div>
</div>

<component
class="p-3"
:class="[elementCssClass(element), { 'prevent-interaction': !element.config.interactive }]"
:tabindex="element.config.interactive ? 0 : -1"
v-bind="element.config"
:config="element.config"
@input="element.config.interactive ? element.config.content = $event : null"
:is="element['editor-component']"
/>
</div>
</div>
</div>
</draggable>
</div>
<component
v-bind="element.config"
:is="element['editor-component']"
class="p-3"
:class="[
elementCssClass(element),
{ 'prevent-interaction': !element.config.interactive }
]"
:tabindex="element.config.interactive ? 0 : -1"
:config="element.config"
@input="
element.config.interactive
? (element.config.content = $event)
: null
"
/>
</div>
</div>
</div>
</draggable>
</div>
</template>

<script>
import draggable from 'vuedraggable';
import { HasColorProperty } from '@/mixins';
import * as renderer from '@/components/renderer';
import _ from 'lodash';
import draggable from "vuedraggable";
import _ from "lodash";
import {
FormInput,
FormSelectList,
FormTextArea,
FormCheckbox,
FormDatePicker,
FormHtmlEditor,
FormHtmlViewer,
} from '@processmaker/vue-form-elements';
FormInput,
FormSelectList,
FormTextArea
} from "@processmaker/vue-form-elements";
import { HasColorProperty } from "@/mixins";
import * as renderer from "@/components/renderer";

export default {
name: 'Loop',
mixins: [HasColorProperty],
props: ['value', 'name', 'config', 'selected', 'validationErrors'],
name: "Loop",
components: {
draggable,
FormInput,
Expand All @@ -133,14 +149,27 @@ export default {
FormDatePicker,
FormHtmlEditor,
FormHtmlViewer,
...renderer,
...renderer
},
mixins: [HasColorProperty],
props: ["value", "name", "config", "selected", "validationErrors"],
data() {
return {
items: [],
cancelledJobs: []
};
},
watch: {
value: {
handler() {
this.items = this.value;
},
immediate: true
},
items() {
this.$emit("input", this.items);
}
},
mounted() {
if (
!localStorage.getItem("cancelledJobs") ||
Expand All @@ -157,34 +186,25 @@ export default {
this.updateProgress(progress, nonce);
});
},
watch: {
value: {
handler() {
this.items = this.value;
},
immediate: true,
},
items() {
this.$emit('input', this.items);
},
},
methods: {
hasError(element) {
if (!this.validationErrors) { return false; }
if (!this.validationErrors) {
return false;
}
return this.validationErrors.some(({ item }) => item === element);
},
inspect(element) {
this.$emit('inspect', element);
this.$emit("inspect", element);
},
deleteItem(index) {
// Remove the item from the array in currentPage
this.items.splice(index, 1);
this.$emit('update-state');
this.$emit("update-state");
},
duplicateItem(index) {
const duplicate = _.cloneDeep(this.items[index]);
this.items.push(duplicate);
this.$emit('update-state');
this.$emit("update-state");
},
isAiSection(element) {
return element.component === "AiSection";
Expand Down Expand Up @@ -226,7 +246,7 @@ export default {
.hasError {
border: 1px solid red;
border-radius: 0.25rem;

.form-element-header {
border-bottom: 1px solid red;
color: red;
Expand All @@ -245,25 +265,25 @@ export default {

.control-item {
position: relative;

.delete {
position: absolute;
top: 0px;
right: 0px;
display: none;
}

&.selected,
&:hover {
.mask {
border: 1px solid red;
}

.delete {
display: inline-block;
}
}

.mask {
position: absolute;
top: 0px;
Expand Down
Loading
Loading