Skip to content

Commit

Permalink
Merge pull request #1710 from ProcessMaker/feature/FOUR-18109
Browse files Browse the repository at this point in the history
Feature/FOUR-18109: STORY Column Configuration for Collections y Record List
  • Loading branch information
nolanpro authored Oct 4, 2024
2 parents 7e70c77 + 6280e1a commit 4e5bfba
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 28 deletions.
1 change: 1 addition & 0 deletions src/components/accordions.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default [
},
fields: [
'fields',
'paginationOption',
{ name: 'options', hideFor: 'FormMultiColumn' },
],
open: false,
Expand Down
63 changes: 59 additions & 4 deletions src/components/inspector/collection-data-source.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@
v-model="sourceOptions"
:options="sourceDisplayOptions"
data-cy="inspector-collection-data-source"
@change="displayOptionChange"
/>
<small class="form-text text-muted">{{
$t("A record list can display the data of a defined variable or a collection")
}}</small>
</div>
<div class="mt-2" v-if="sourceOptions === 'Collection'">

<CollectionRecordsList
v-model="collectionFields"
:record-pmql="pmql"/>
:record-pmql="pmql"
@change="collectionChanged"/>

<pmql-input
v-model="pmql"
Expand All @@ -27,7 +32,7 @@
>
</pmql-input>
<small class="form-text text-muted">{{
$t("Advanced data search")
$t("Leave this field empty to show all the records of the collection")
}}</small>
<label for="collectionsource">{{ $t("Data Selection") }}</label>

Expand All @@ -50,9 +55,11 @@
<script>
import CollectionRecordsList from "./collection-records-list.vue"
import { cloneDeep } from "lodash";
const CONFIG_FIELDS = [
"collectionFields",
"collectionFieldsColumns",
"pmql",
"sourceOptions"
Expand All @@ -69,6 +76,7 @@
submitCollectionCheck: true,
sourceDisplayOptions: [],
collectionFields: [],
collectionFieldsColumns: [],
pmql: null,
sourceDisplayOptions: [
{
Expand All @@ -82,6 +90,47 @@
]
};
},
methods: {
displayOptionChange() {
this.collectionFields = [];
this.collectionFieldsColumns = [];
this.pmql = null;
this.$root.$emit("collection-changed", true);
},
collectionChanged(data) {
if (Array.isArray(data)) {
const [firstItem] = data;
const collectionId = firstItem?.collection_id;
if(collectionId !== this.collectionFields.collectionId) {
this.$root.$emit("collection-changed", true);
}
}
},
changeCollectionColumns(columnsSelected) {
let selectedKeys = columnsSelected.map(column => column.content);
if (Array.isArray(this.collectionFieldsColumns?.dataRecordList)) {
this.collectionFieldsColumns.dataRecordList.forEach(record => {
let dataObject = record.data;
if (dataObject && typeof dataObject === 'object') {
Object.keys(dataObject).forEach(key => {
if (!selectedKeys.includes(key)) {
delete dataObject[key];
} else {
const matchingColumn = columnsSelected.find(column => column.content === key);
if (matchingColumn && matchingColumn.key !== key) {
dataObject[matchingColumn.key] = dataObject[key];
delete dataObject[key];
}
}
});
}
});
}
}
},
computed: {
options() {
return Object.fromEntries(
Expand All @@ -100,10 +149,16 @@
immediate: true
},
sourceOptions: {
handler() {
handler(changeOption) {
this.$root.$emit("record-list-option", changeOption);
}
},
collectionFields: {
handler(collectionFieldsData) {
this.$root.$emit("record-list-collection", collectionFieldsData);
},
deep: true
},
pmql: {
handler(newPmql) {
this.$root.$emit("change-pmql", newPmql);
Expand Down
2 changes: 1 addition & 1 deletion src/components/inspector/collection-records-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export default {
mounted() {
this.$root.$on("change-pmql", (val) => {
this.pmql = val;
this.onCollectionChange();
});
this.getCollections();
if (this.collectionId) {
Expand All @@ -90,6 +89,7 @@ export default {
.then((response) => {
this.dataRecordList = response.data;
});
this.$emit('change', this.dataRecordList);
},
getCollections() {
this.$dataProvider.getCollections().then((response) => {
Expand Down
130 changes: 123 additions & 7 deletions src/components/inspector/column-setup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<div v-else class="card-header">
{{ $t('Edit Column') }}
</div>
<div class="card-body p-2">
<div v-if="!isCollection" class="card-body p-2">
<label class="mt-3" for="option-content">{{ $t('Column Header') }}</label>
<b-form-input id="option-content" v-model="optionContent"/>
<label for="option-value">{{ $t('Value') }}</label>
Expand All @@ -26,12 +26,27 @@
<div>{{ optionError }}</div>
</div>
</div>
<div v-else class="card-body p-2">
<label class="mt-3" for="option-content">{{ $t('Column') }}</label>
<b-form-select
id="columnCollection"
v-model="optionValueCollection"
:options="collectionOptions"
data-cy="inspector-collection-columns"
@change="handleColumnSelection"
/>
<label v-show="!hideLabelAll" for="option-label-column">{{ $t('Column Label') }}</label>
<b-form-input v-show="!hideLabelAll" id="option-label-column" v-model="optionContentCollection" :classs="optionKeyClass" />
<div v-if="optionError" class="invalid-feedback d-block text-right">
<div>{{ optionError }}</div>
</div>
</div>

<div class="card-footer text-right p-2">
<button type="button" class="btn btn-sm btn-outline-secondary mr-2" @click="showOptionCard=false">
{{ $t('Cancel') }}
</button>
<button type="button" class="btn btn-sm btn-secondary" @click="addOption()">
<button type="button" class="btn btn-sm btn-secondary" @click="isCollection ? addOptionCollection() : addOption()">
{{ $t('Save') }}
</button>
</div>
Expand Down Expand Up @@ -65,7 +80,7 @@
<div v-else class="card-header">
{{ $t('Edit Option') }}
</div>
<div class="card-body p-2">
<div v-if="!isCollection" class="card-body p-2">
<label class="mt-3" for="option-content">{{ $t('Column Header') }}</label>
<b-form-input id="option-content" v-model="optionContent"/>
<label for="option-value">{{ $t('Value') }}</label>
Expand All @@ -74,12 +89,26 @@
<div>{{ optionError }}</div>
</div>
</div>
<div v-else class="card-body p-2">
<label class="mt-3" for="option-content-collection">{{ $t('Column') }}</label>
<b-form-select
id="columnCollection"
v-model="optionValueCollection"
:options="collectionOptions"
data-cy="inspector-collection-columns"
/>
<label for="option-value-collection">{{ $t('Column Label') }}</label>
<b-form-input id="option-value-collection" v-model="optionContentCollection" :classs="optionKeyClass" />
<div v-if="optionError" class="invalid-feedback d-block text-right">
<div>{{ optionError }}</div>
</div>
</div>

<div class="card-footer text-right p-2">
<button type="button" class="btn btn-sm btn-outline-secondary mr-2" @click="editIndex=null">
{{ $t('Cancel') }}
</button>
<button type="button" class="btn btn-sm btn-secondary" @click="addOption()">
<button type="button" class="btn btn-sm btn-secondary" @click="isCollection ? addOptionCollection() : addOption()">
{{ $t('Update') }}
</button>
</div>
Expand Down Expand Up @@ -186,6 +215,7 @@
import draggable from 'vuedraggable';
import { dataSources, dataSourceValues } from './data-source-types';
import MonacoEditor from 'vue-monaco';
import { cloneDeep } from "lodash";
export default {
components: {
Expand Down Expand Up @@ -219,6 +249,8 @@ export default {
removeIndex: null,
optionValue: '',
optionContent: '',
optionValueCollection: '',
optionContentCollection: '',
showRenderAs: false,
renderAs: 'dropdown',
allowMultiSelect: false,
Expand All @@ -242,6 +274,9 @@ export default {
automaticLayout: true,
},
showPopup: false,
isCollection: null,
collectionOptions: [],
hideLabelAll: false
};
},
watch: {
Expand Down Expand Up @@ -284,6 +319,9 @@ export default {
keyField() {
return this.key || 'value';
},
keyFieldCollection() {
return this.key || 'key';
},
valueField() {
return this.value || 'content';
},
Expand Down Expand Up @@ -321,8 +359,53 @@ export default {
},
mounted() {
this.initData();
this.$root.$on("record-list-option", (val) => {
this.$nextTick(()=>{
this.isCollection = (val === "Collection") ? true : false;
});
});
this.$root.$on("record-list-collection", (collectionData) => {
this.getCollectionColumns(collectionData);
});
this.$root.$on("collection-changed", (change) => {
if(change) {
this.optionsList = [];
}
});
this.$root.$on("option-source-changed", (change) => {
if(change) {
this.optionsList = [];
}
});
},
methods: {
handleColumnSelection() {
if (this.optionValueCollection === "all") {
this.optionsList = [];
this.hideLabelAll = true;
this.collectionOptions.forEach(option => {
if(option.value !== "all") {
this.optionsList.push({
content: option.value,
key: option.value
});
}
});
}
},
getCollectionColumns(collection) {
this.collectionOptions = [{ text: "All columns", value: "all" }];
const [firstRecord] = collection?.dataRecordList || [];
if (firstRecord?.data) {
const dataObject = firstRecord.data;
for (const [key, value] of Object.entries(dataObject)) {
this.collectionOptions.push({ text: key, value: key });
}
}
},
initData() {
this.dataSource = this.options.dataSource;
this.jsonData = this.options.jsonData;
Expand Down Expand Up @@ -391,12 +474,16 @@ export default {
this.editIndex = index;
this.optionContent = this.optionsList[index][this.valueField];
this.optionValue = this.optionsList[index][this.keyField];
this.optionContentCollection = this.optionsList[index][this.keyFieldCollection];
this.optionValueCollection = this.optionsList[index][this.valueField];
this.optionError = '';
},
showAddOption() {
this.optionCardType = 'insert';
this.optionContent = '';
this.optionValue = '';
this.optionContentCollection = '';
this.optionValueCollection = '';
this.showOptionCard = true;
this.optionError = '';
this.editIndex = null;
Expand All @@ -412,6 +499,7 @@ export default {
this.optionError = 'An item with the same key already exists';
return;
}
this.optionsList.push(
{
[this.valueField]: this.optionContent,
Expand All @@ -420,7 +508,7 @@ export default {
);
}
else {
if (this.optionsList.find((item, index) => { return item[that.keyField] === this.optionValue && index !== this.editIndex ; })) {
if (this.optionsList.find((item, index) => { return item[that.keyField] === this.optionValue && index !== this.editIndex; })) {
this.optionError = 'An item with the same key already exists';
return;
}
Expand All @@ -434,19 +522,47 @@ export default {
this.optionError = '';
this.editIndex = null;
},
addOptionCollection() {
const that = this;
if (this.optionsList === undefined) {
this.initData();
}
if (this.optionCardType === 'insert') {
if (this.optionsList.find(item => { return item[that.keyFieldCollection] === this.optionContentCollection; })) {
this.optionError = 'An item with the same key already exists';
return;
}
this.optionsList.push(
{
[this.keyFieldCollection]: this.optionContentCollection,
[this.valueField]: this.optionValueCollection,
}
);
this.optionsList = this.optionsList.filter(option => option["content"] !== "all");
}
else {
this.optionsList[this.editIndex][this.keyFieldCollection] = this.optionContentCollection;
this.optionsList[this.editIndex][this.valueField] = this.optionValueCollection;
}
this.jsonError = '';
this.jsonData = JSON.stringify(this.optionsList);
this.showOptionCard = false;
this.optionError = '';
this.editIndex = null;
},
deleteOption() {
this.optionsList.splice(this.removeIndex, 1);
this.jsonData = JSON.stringify(this.optionsList);
this.showRemoveWarning = false;
this.removeIndex = null;
},
removeOption(index) {
this.removeIndex = index;
this.showRemoveWarning = true;
},
expandEditor() {
this.showPopup = true;
},
Expand Down
1 change: 1 addition & 0 deletions src/components/inspector/page-select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
:show-labels="false"
:options="options.map(option => option.value)"
:custom-label="getLabelFromValue"
data-cy="inspector-eventData"
>
<template slot="noResult">
{{ $t('No elements found. Consider changing the search query.') }}
Expand Down
Loading

0 comments on commit 4e5bfba

Please sign in to comment.