demf-mashups-editor 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,352 @@
1
+ # Digital Enabler Mashups Editor
2
+
3
+ The Mashups Editor microfrontend provides a visual node-based editor for creating and modifying mashups using Vue Flow. Allows users to drag-and-drop operators, connect them, and configure their properties. Integrates with the mashups editor appbar for a complete mashup editing experience.
4
+
5
+ Built with **Vue 3**, **Vuetify 3**, and **Vite**. Designed for **Single-SPA** integration.
6
+
7
+ > πŸ“Œ **See also:**
8
+ > - [Root Config integration guide](https://github.com/digital-enabler/root-config-microfrontend-vite-template)
9
+ > - [Microfrontend template documentation](https://github.com/digital-enabler/vuejs3-microfrontend-vite-template)
10
+
11
+ ---
12
+
13
+ ## πŸ“¦ Installation
14
+
15
+
16
+ ### Via CDN
17
+
18
+ This project is available from the following CDN:
19
+
20
+ ```
21
+ https://cdn.jsdelivr.net/npm/demf-Mashups Editor@latest/mf-app.js
22
+ ```
23
+
24
+ Add it to your root-config import map:
25
+
26
+ ```json
27
+ {
28
+ "imports": {
29
+ "demf-Mashups Editor": "https://cdn.jsdelivr.net/npm/demf-Mashups Editor@latest/mf-app.js"
30
+ }
31
+ }
32
+ ```
33
+
34
+ ---
35
+
36
+ ## πŸš€ Quick Start
37
+
38
+ ### Prerequisites
39
+
40
+ Before you continue you need to have:
41
+
42
+ - A Digital Enabler **root-config** application running
43
+ - **Single-SPA** layout engine configured
44
+ - A configuration file for the Mashups Editor (see below)
45
+
46
+ ### Integration Steps
47
+
48
+ **1. Add to Import Map**
49
+
50
+ In your root-config `importmap.json`:
51
+
52
+ ```json
53
+ {
54
+ "imports": {
55
+ "demf-Mashups Editor": "https://cdn.jsdelivr.net/npm/demf-Mashups Editor@latest/mf-app.js"
56
+ }
57
+ }
58
+ ```
59
+
60
+ For local development:
61
+ ```json
62
+ {
63
+ "imports": {
64
+ "demf-Mashups Editor": "http://localhost:9012/mf-app.js"
65
+ }
66
+ }
67
+ ```
68
+
69
+ **2. Register in Layout**
70
+
71
+ In your root-config layout HTML:
72
+
73
+ ```html
74
+ <application
75
+ name="demf-Mashups Editor"
76
+ props="realm, palette, Mashups Editor-config">
77
+ </application>
78
+ ```
79
+
80
+ **3. Create Configuration File**
81
+
82
+ Create a `Mashups Editor-config.json` file with these settings:
83
+
84
+ ```json
85
+ {
86
+ "name": "mashups-editor",
87
+ "mf": "demf-Mashups Editor",
88
+ "api": "https://[generic_api_location]/api"
89
+ }
90
+ ```
91
+
92
+ This JSON file must be:
93
+ - Stored in a location accessible to the root-config
94
+ - Included in the root-config's remote configuration
95
+ - Passed as the `Mashups Editor-config` prop to the microfrontend
96
+
97
+ > πŸ“– For details on configuration management, see:
98
+ > - [Microfrontend Template Guide](https://github.com/digital-enabler/vuejs3-microfrontend-vite-template)
99
+ > - [Root Config Documentation](https://github.com/digital-enabler/root-config-microfrontend-vite-template)
100
+
101
+ ---
102
+
103
+ ## βš™οΈ Configuration
104
+
105
+ The Mashups Editor microfrontend receives a configuration object via the `Mashups Editor-config` prop:
106
+
107
+ ```json
108
+ {
109
+ "name": "mashups-editor",
110
+ "mf": "demf-Mashups Editor",
111
+ "api": "https://your-api-endpoint.com/api"
112
+ }
113
+ ```
114
+
115
+ ### Configuration Fields
116
+
117
+ | Field | Type | Required | Description |
118
+ |-------|------|----------|-------------|
119
+ | `mf` | string | Yes | Microfrontend identifier (use "demf-Mashups Editor") |
120
+ | `api` | string | Yes | Base URL for API calls |
121
+
122
+ ### Additional Props from Root-Config
123
+
124
+ The microfrontend also receives these props automatically from the root-config:
125
+
126
+ - **`realm`**: Current tenant/realm identifier
127
+ - **`palette`**: Dynamic theme colors (primary, secondary, etc.)
128
+
129
+ These props are used to:
130
+ - Apply consistent theming across the platform
131
+ - Configure tenant-specific behavior
132
+ - Adapt the Mashups Editor appearance to the current application theme
133
+
134
+ ---
135
+
136
+ ## πŸ› οΈ Development
137
+
138
+ ### Prerequisites
139
+
140
+ Before you continue you need to have:
141
+
142
+ - [NPM](https://www.npmjs.com/) installed
143
+ - [Node.js](https://nodejs.org/) (v22+ or v24.8+) installed
144
+ - [Vue.js](https://v3.vuejs.org/) and [Vite](https://vitejs.dev/) knowledge
145
+ - A [GitHub](https://github.com/) account
146
+ - Visual Studio Code or IntelliJ IDEA as your development IDE
147
+
148
+ ### Project Management
149
+
150
+ #### Installation
151
+
152
+ Open a **Terminal** window in the project folder and go inside the `app` folder, then launch:
153
+
154
+ ```bash
155
+ npm install
156
+ ```
157
+
158
+ > **NOTE:** When install finishes, do not worry about warnings on versions and vulnerability problems reported. **DO NOT** launch `npm audit fix` or `npm audit fix --force` commands.
159
+
160
+ #### Development Server (with hot-reload)
161
+
162
+ ```bash
163
+ npm run dev
164
+ ```
165
+
166
+ This command:
167
+ 1. Generates Vuetify locales automatically (via `predev` script)
168
+ 2. Builds the microfrontend in watch mode
169
+ 3. Starts a preview server at `http://localhost:9012`
170
+
171
+ The microfrontend will be available at: `http://localhost:9012/mf-app.js`
172
+
173
+ #### Build for Production
174
+
175
+ ```bash
176
+ npm run build
177
+ ```
178
+
179
+ This command:
180
+ 1. Generates Vuetify locales automatically (via `prebuild` script)
181
+ 2. Creates an optimized production build in the `dist/` folder
182
+ 3. Outputs a SystemJS bundle ready for deployment
183
+
184
+ #### Code Quality
185
+
186
+ ```bash
187
+ npm run lint # Lint and fix files with ESLint
188
+ npm run format # Format code with Prettier
189
+ ```
190
+
191
+ > **NOTE:** Alternatively to the commands indicated above you can use the Vue UI browser interface.
192
+
193
+ ---
194
+
195
+ ## 🌐 Internationalization
196
+
197
+ The Mashups Editor microfrontend supports multiple languages through **vue-i18n** with automatic **Vuetify locale integration**.
198
+
199
+ ### How It Works
200
+
201
+ - Locale files are stored in `src/locales/*.json` (e.g., `en.json`, `it.json`)
202
+ - The script `scripts/generate-vuetify-locales.mjs` automatically scans these files
203
+ - Matching Vuetify translations are imported and merged
204
+ - The active language is read from `localStorage.getItem('lang')` (defaults to `en`)
205
+
206
+ ### Supported Languages
207
+
208
+ The Mashups Editor includes translations for the languages defined in `src/locales/`:
209
+ - English (`en`)
210
+ - Italian (`it`)
211
+ - [Add other languages as needed]
212
+
213
+ ### Adding a New Language
214
+
215
+ 1. Create a new file: `src/locales/<code>.json` (e.g., `es.json`)
216
+ 2. Add your translations following the existing structure
217
+ 3. Run `npm run dev` or `npm run build`
218
+ 4. The generator will automatically include Vuetify translations for that language
219
+
220
+ ---
221
+
222
+ ## 🎨 Features
223
+
224
+ - **Dynamic theming**: Automatically adapts to the palette passed from root-config
225
+ - **Multi-language support**: Full internationalization with vue-i18n
226
+ - **Responsive design**: Works seamlessly on mobile, tablet, and desktop
227
+ - **Material Design**: Built with Vuetify 3 components and Material Design Icons
228
+ - **Consistent branding**: Shows uniform Mashups Editor across all Digital Enabler services
229
+ - **Platform information**: Displays version, copyright, and relevant links
230
+
231
+ ---
232
+
233
+ ## πŸ“ Project Structure
234
+
235
+ ```
236
+ demf-Mashups Editor/
237
+ β”œβ”€β”€ app/
238
+ β”‚ β”œβ”€β”€ src/
239
+ β”‚ β”‚ β”œβ”€β”€ App.vue # Main component
240
+ β”‚ β”‚ β”œβ”€β”€ main.js # Entry point
241
+ β”‚ β”‚ β”œβ”€β”€ components/ # Mashups Editor components
242
+ β”‚ β”‚ β”œβ”€β”€ locales/
243
+ β”‚ β”‚ β”‚ β”œβ”€β”€ i18n.js # i18n configuration
244
+ β”‚ β”‚ β”‚ β”œβ”€β”€ en.json # English translations
245
+ β”‚ β”‚ β”‚ β”œβ”€β”€ it.json # Italian translations
246
+ β”‚ β”‚ β”‚ └── vuetify-generated.js # Auto-generated Vuetify locales
247
+ β”‚ β”‚ β”œβ”€β”€ plugins/
248
+ β”‚ β”‚ β”‚ └── vuetify.js # Vuetify configuration
249
+ β”‚ β”‚ β”œβ”€β”€ router/
250
+ β”‚ β”‚ └── store/
251
+ β”‚ β”œβ”€β”€ scripts/
252
+ β”‚ β”‚ └── generate-vuetify-locales.mjs
253
+ β”‚ β”œβ”€β”€ public/
254
+ β”‚ β”œβ”€β”€ dist/ # Build output
255
+ β”‚ β”œβ”€β”€ package.json
256
+ β”‚ β”œβ”€β”€ vite.config.js
257
+ β”‚ └── eslint.config.js
258
+ β”œβ”€β”€ docker/
259
+ └── README.md
260
+ ```
261
+
262
+ ---
263
+
264
+ ## πŸ” Troubleshooting
265
+
266
+ ### Mashups Editor not visible
267
+
268
+ - Verify the import map includes `demf-Mashups Editor`
269
+ - Check the layout HTML has the `<application>` tag with correct name
270
+ - Ensure the bundle is accessible at the configured URL
271
+ - Look for console errors in the browser developer tools
272
+
273
+ ### Configuration not working
274
+
275
+ - Check that `Mashups Editor-config` prop is passed in the layout
276
+ - Verify the configuration JSON structure matches the expected format
277
+ - Ensure the root-config is loading the remote configuration correctly
278
+ - Check console for warnings about missing configuration
279
+
280
+ ### Styling issues
281
+
282
+ - Ensure the `palette` prop is being passed from root-config
283
+ - Verify Material Design Icons fonts are loaded
284
+ - Check that Vuetify theme configuration is correct
285
+ - Clear browser cache and reload
286
+
287
+ ### API connection errors
288
+
289
+ - Verify the `api` field in `Mashups Editor-config.json` is correct
290
+ - Check network tab for failed API requests
291
+ - Ensure CORS is properly configured on the backend
292
+ - Verify the API endpoint is accessible from the browser
293
+
294
+ ### Development server not starting
295
+
296
+ - Check that port 9012 is not already in use
297
+ - Verify Node.js version is compatible (v22+ or v24.8+)
298
+ - Try removing `node_modules` and running `npm install` again
299
+ - Ensure all dependencies are correctly installed
300
+
301
+ ---
302
+
303
+ ## πŸ“š Tech Stack
304
+
305
+ ### Runtime Dependencies
306
+
307
+ - **Vue 3** (^3.5.22) - Progressive JavaScript framework
308
+ - **Vuetify 3** (^3.10.7) - Material Design component library
309
+ - **Single-SPA Vue** (^3.0.1) - Single-SPA integration for Vue
310
+ - **Vue Router** (^4.6.3) - Official router for Vue.js
311
+ - **Vue i18n** (^9.14.5) - Internationalization plugin
312
+ - **Vuex** (^4.1.0) - State management
313
+ - **Axios** (^1.13.0) - HTTP client
314
+ - **Material Design Icons** (^7.4.47) - Icon library
315
+
316
+ ### Development Dependencies
317
+
318
+ - **Vite** (^7.1.12) - Next generation frontend tooling
319
+ - **ESLint** (^9.38.0) - Code linting
320
+ - **Prettier** (^3.6.2) - Code formatting
321
+ - **Vite Plugin Vue DevTools** (^8.0.3) - Vue DevTools integration
322
+ - **Concurrently** (^9.2.1) - Run multiple commands
323
+
324
+ For complete dependencies, see [`package.json`](./app/package.json).
325
+
326
+ ---
327
+
328
+ ## πŸ“– Related Documentation
329
+
330
+ - [Digital Enabler Root Config Template](https://github.com/digital-enabler/root-config-microfrontend-vite-template)
331
+ - [Digital Enabler Microfrontend Template](https://github.com/digital-enabler/vuejs3-microfrontend-vite-template)
332
+ - [Single-SPA Documentation](https://single-spa.js.org/)
333
+ - [Vue 3 Documentation](https://vuejs.org/)
334
+ - [Vuetify 3 Documentation](https://vuetifyjs.com/)
335
+ - [Vite Documentation](https://vitejs.dev/)
336
+
337
+ ---
338
+
339
+ ## πŸ“„ License
340
+
341
+ This project is part of Digital Enabler Ecosystem.
342
+
343
+ Β© 2025 Engineering Ingegneria Informatica S.p.A.
344
+
345
+ ---
346
+
347
+ ## πŸ†˜ Support
348
+
349
+ For support, questions, or issues:
350
+ - Open an issue on [GitHub](https://github.com/digital-enabler/demf-Mashups Editor/issues)
351
+ - Contact the Digital Enabler development team
352
+ - Check the [Digital Enabler documentation](https://github.com/digital-enabler)
@@ -0,0 +1,3 @@
1
+ System.register(["./main-hhWt7S1o.js","single-spa-vue"],(function(J,q){"use strict";var U,_,O,f,E,N,g,c,u,w,R,W,I,S,h,$,x;return{setters:[r=>{U=r._,_=r.r,O=r.c,f=r.o,E=r.F,N=r.a,g=r.b,c=r.w,u=r.d,w=r.e,R=r.n,W=r.f,I=r.i,S=r.g,h=r.h,$=r.j,x=r.k},null],execute:(function(){var r=document.createElement("style");r.textContent=`.not-allowed[data-v-493e51e9]{cursor:default}
2
+ /*$vite$:1*/`,document.head.appendChild(r);const A={props:["dynamicParams","data"],setup(n){const i=I("formData"),B=JSON.parse(JSON.stringify(i.parameters)),a=S(V(B)),F=["=","!=","<",">","<=",">=","includes","not includes","matches","exists"],b=h(()=>n.dynamicParams.showOperatorColumn),y=h(()=>n.dynamicParams.showValueColumn),m=h(()=>n.data.content),k=h(()=>m.value?$(n.data.content):n.dynamicParams.propertyOptions);x(k,e=>{for(let t of i.dynamicParams)if(t.blockId==n.dynamicParams.blockId)return t.propertyOptions=e,t}),x(a,()=>{let e=[];if(a.value.forEach((t,l)=>{t.property&&(!b.value||t.operator)&&(!y.value||t.operator==="exists"||t.value)&&(t.complete=!0,e.push(...o(t,l)),a.value[l+1]||a.value.push({property:null,operator:null,value:"",complete:!1}))}),e.length>0){i.parameters=i.parameters.filter(s=>!s.name.startsWith("__key__")&&!s.name.startsWith("__operator_")&&!s.name.startsWith("__item_"));let t=[...i.parameters,...e],l=new Set;i.parameters=t.filter(s=>{let d=JSON.stringify(s);return l.has(d)?!1:(l.add(d),!0)})}},{deep:!0});function C(e,t){e&&this.removeRow(t)}function P(e){a.value.splice(e,1)}function o(e,t){let l=[];return e.complete&&(l.push({name:`__key__${t}`,property:e.property,bind:!0,custom:!0}),b.value&&e.operator&&l.push({name:`__operator_${t}`,property:e.operator,bind:!0,custom:!0}),y.value&&e.value&&l.push({name:`__item_${t}`,property:e.value,bind:!0,custom:!0})),l}function V(e){if(!Array.isArray(e)){console.error("Error: objects must be an array.");return}if(e.length===0)return[{property:null,operator:null,value:"",complete:!1}];let t={};e.forEach(d=>{let p=d.name.split("_").reverse()[0];t[p]||(t[p]=[]),t[p].push(d)});let l=Object.values(t).map(d=>{let p={property:null,operator:null,value:"",complete:!0};return d.forEach(v=>{v.name.startsWith("__key__")?p.property=v.property:v.name.startsWith("__operator_")?p.operator=v.property:v.name.startsWith("__item_")&&(p.value=v.property)}),p}),s=l[l.length-1];return s.property===null&&s.operator===null&&s.value===""&&(s.complete=!1),l}return{rows:a,operators:F,showOperatorColumn:b,showValueColumn:y,properties:k,removeRow:P,generateObjects:o,handleIconClick:C}}},D={class:"mb-2"};function j(n,i,B,a,F,b){const y=_("v-select"),m=_("v-col"),k=_("v-text-field"),C=_("v-row"),P=_("v-icon");return f(),O("div",D,[(f(!0),O(E,null,N(a.rows,(o,V)=>(f(),g(C,{key:V,dense:!0,"no-gutters":!0,align:"start",justify:"space-between"},{default:c(()=>[u(m,{cols:"11"},{default:c(()=>[u(C,{dense:!0,"no-gutters":!1,class:"mb-2"},{default:c(()=>[u(m,{cols:a.showOperatorColumn?12:"auto",lg:"4"},{default:c(()=>[u(y,{items:a.properties,modelValue:o.property,"onUpdate:modelValue":e=>o.property=e,label:n.$t("labels.property"),color:"primary",variant:"outlined",density:"compact","hide-details":!0},null,8,["items","modelValue","onUpdate:modelValue","label"])]),_:2},1032,["cols"]),a.showOperatorColumn?(f(),g(m,{key:0,cols:"5",lg:"3"},{default:c(()=>[u(y,{items:a.operators,modelValue:o.operator,"onUpdate:modelValue":e=>o.operator=e,label:n.$t("labels.operator"),class:"mb-4",color:"primary",variant:"outlined",density:"compact","hide-details":!0},null,8,["items","modelValue","onUpdate:modelValue","label"])]),_:2},1024)):w("",!0),a.showValueColumn&&o.operator!=="exists"?(f(),g(m,{key:1,cols:a.showOperatorColumn?7:6,lg:"5"},{default:c(()=>[u(k,{modelValue:o.value,"onUpdate:modelValue":e=>o.value=e,label:n.$t("labels.value"),class:"mb-4",color:"primary",variant:"outlined",density:"compact","hide-details":!0},null,8,["modelValue","onUpdate:modelValue","label"])]),_:2},1032,["cols"])):w("",!0)]),_:2},1024)]),_:2},1024),u(m,{cols:" 1",class:"d-flex justify-center align-start"},{default:c(()=>[u(P,{onClick:e=>a.handleIconClick(o.complete,V),color:o.complete?"secondary":"grey",class:R([{"not-allowed":!o.complete},"mt-2"])},{default:c(()=>[...i[0]||(i[0]=[W(" mdi-delete ",-1)])]),_:1},8,["onClick","color","class"])]),_:2},1024)]),_:2},1024))),128))])}const z=J("default",U(A,[["render",j],["__scopeId","data-v-493e51e9"]]))})}}));
3
+ //# sourceMappingURL=FlexibleRowGridBlock-Diaq03tS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlexibleRowGridBlock-Diaq03tS.js","sources":["../../src/components/blocks/FlexibleRowGridBlock.vue"],"sourcesContent":["<template>\n <div class=\"mb-2\">\n <v-row\n v-for=\"(row, index) in rows\"\n :key=\"index\"\n :dense=\"true\"\n :no-gutters=\"true\"\n align=\"start\"\n justify=\"space-between\"\n >\n <v-col cols=\"11\">\n <v-row :dense=\"true\" :no-gutters=\"false\" class=\"mb-2\">\n <v-col :cols=\"showOperatorColumn ? 12 : 'auto'\" lg=\"4\">\n <v-select\n :items=\"properties\"\n v-model=\"row.property\"\n :label=\"$t('labels.property')\"\n color=\"primary\"\n variant=\"outlined\"\n density=\"compact\"\n :hide-details=\"true\"\n ></v-select>\n </v-col>\n <v-col cols=\"5\" lg=\"3\" v-if=\"showOperatorColumn\">\n <v-select\n :items=\"operators\"\n v-model=\"row.operator\"\n :label=\"$t('labels.operator')\"\n class=\"mb-4\"\n color=\"primary\"\n variant=\"outlined\"\n density=\"compact\"\n :hide-details=\"true\"\n ></v-select>\n </v-col>\n <v-col\n :cols=\"showOperatorColumn ? 7 : 6\"\n lg=\"5\"\n v-if=\"showValueColumn && row.operator !== 'exists'\"\n >\n <v-text-field\n v-model=\"row.value\"\n :label=\"$t('labels.value')\"\n class=\"mb-4\"\n color=\"primary\"\n variant=\"outlined\"\n density=\"compact\"\n :hide-details=\"true\"\n ></v-text-field>\n </v-col>\n </v-row>\n </v-col>\n <v-col cols=\" 1\" class=\"d-flex justify-center align-start\">\n <v-icon\n @click=\"handleIconClick(row.complete, index)\"\n :color=\"row.complete ? 'secondary' : 'grey'\"\n :class=\"{ 'not-allowed': !row.complete }\"\n class=\"mt-2\"\n >\n mdi-delete\n </v-icon>\n </v-col>\n </v-row>\n </div>\n</template>\n\n<script>\nimport { inject, ref, computed, watch } from \"vue\";\nimport { getUniqueKeys } from \"@/mixins/common-utils.js\";\n\nexport default {\n props: [\"dynamicParams\", \"data\"],\n setup(props) {\n const formData = inject(\"formData\");\n const blockParams = JSON.parse(JSON.stringify(formData.parameters));\n const rows = ref(generateRows(blockParams));\n const operators = [\n \"=\",\n \"!=\",\n \"<\",\n \">\",\n \"<=\",\n \">=\",\n \"includes\",\n \"not includes\",\n \"matches\",\n \"exists\",\n ];\n\n const showOperatorColumn = computed(\n () => props.dynamicParams.showOperatorColumn,\n );\n const showValueColumn = computed(() => props.dynamicParams.showValueColumn);\n const inputContent = computed(() => props.data.content); //'content' is defined as prop inside InputBlock component slot\n const properties = computed(() => {\n return inputContent.value\n ? getUniqueKeys(props.data.content)\n : props.dynamicParams.propertyOptions;\n });\n\n // Watch for changes in properties\n watch(properties, (newProperties) => {\n // Iterate over each object in the dynamicParams of the Operator\n for (let param of formData.dynamicParams) {\n // Check the blockId with the same name of this component\n if (param.blockId == props.dynamicParams.blockId) {\n param.propertyOptions = newProperties;\n // Return the parameter\n return param;\n }\n }\n });\n\n watch(\n rows,\n () => {\n let transformedRows = [];\n rows.value.forEach((row, index) => {\n if (\n row.property &&\n (!showOperatorColumn.value || row.operator) &&\n (!showValueColumn.value || row.operator === \"exists\" || row.value)\n ) {\n row.complete = true;\n transformedRows.push(...generateObjects(row, index));\n if (!rows.value[index + 1]) {\n rows.value.push({\n property: null,\n operator: null,\n value: \"\",\n complete: false,\n });\n }\n }\n });\n if (transformedRows.length > 0) {\n // First, remove existing objects with the same name\n formData.parameters = formData.parameters.filter((item) => {\n return (\n !item.name.startsWith(\"__key__\") &&\n !item.name.startsWith(\"__operator_\") &&\n !item.name.startsWith(\"__item_\")\n );\n });\n // Merge transformedRows with the existing data in formData.parameters\n let combined = [...formData.parameters, ...transformedRows];\n // Create a Set to store the string versions of the objects\n let set = new Set();\n // Filter duplicates\n formData.parameters = combined.filter((item) => {\n // Convert the object to a string\n let key = JSON.stringify(item);\n // Check if the string is already in the Set\n if (!set.has(key)) {\n // If it's not in the Set, add it and keep the object in the array\n set.add(key);\n return true;\n }\n // If the string is already in the Set, remove the object from the array\n return false;\n });\n }\n },\n { deep: true },\n );\n\n function handleIconClick(isComplete, index) {\n if (isComplete) {\n this.removeRow(index);\n }\n }\n\n function removeRow(index) {\n rows.value.splice(index, 1);\n }\n\n /**\n * This method generates an array of objects based on the completed rows in the component.\n * Each object corresponds to the property, operator, and value from that row.\n * The 'property' is always included in the objects as it is always present in the rows.\n * The 'operator' and 'value' are included only if their respective columns are shown and have been filled out by the user.\n * The method filters out any rows that are not marked as complete.\n */\n function generateObjects(row, index) {\n let objects = [];\n if (row.complete) {\n objects.push({\n name: `__key__${index}`,\n property: row.property,\n bind: true,\n custom: true,\n });\n if (showOperatorColumn.value && row.operator) {\n objects.push({\n name: `__operator_${index}`,\n property: row.operator,\n bind: true,\n custom: true,\n });\n }\n if (showValueColumn.value && row.value) {\n objects.push({\n name: `__item_${index}`,\n property: row.value,\n bind: true,\n custom: true,\n });\n }\n }\n return objects;\n }\n\n /**\n * This function takes an array of objects and generates a corresponding array of 'row' objects.\n * Each 'row' object corresponds to a group of objects in the input array that have the same index.\n * The 'property', 'operator', and 'value' are extracted from each group of objects and used to create the 'row' object.\n * All generated 'row' objects are marked as complete.\n */\n function generateRows(objects) {\n // Check if objects is an array\n if (!Array.isArray(objects)) {\n console.error(\"Error: objects must be an array.\");\n return;\n }\n // If objects is empty, return an array with a single row with null values and complete set to false\n if (objects.length === 0) {\n return [{ property: null, operator: null, value: \"\", complete: false }];\n }\n // Group the objects by index\n let groups = {};\n objects.forEach((obj) => {\n let index = obj.name.split(\"_\").reverse()[0];\n if (!groups[index]) {\n groups[index] = [];\n }\n groups[index].push(obj);\n });\n // Generate the 'row' objects from the groups\n let rows = Object.values(groups).map((group) => {\n let row = {\n property: null,\n operator: null,\n value: \"\",\n complete: true, // Set complete to true for converted rows\n };\n group.forEach((obj) => {\n if (obj.name.startsWith(\"__key__\")) {\n row.property = obj.property;\n } else if (obj.name.startsWith(\"__operator_\")) {\n row.operator = obj.property;\n } else if (obj.name.startsWith(\"__item_\")) {\n row.value = obj.property;\n }\n });\n\n return row;\n });\n // Check the last object: if its values are all null, set complete to false\n let lastRow = rows[rows.length - 1];\n if (\n lastRow.property === null &&\n lastRow.operator === null &&\n lastRow.value === \"\"\n ) {\n lastRow.complete = false;\n }\n return rows;\n }\n\n return {\n rows,\n operators,\n showOperatorColumn,\n showValueColumn,\n properties,\n removeRow,\n generateObjects,\n handleIconClick,\n };\n },\n};\n</script>\n\n<style scoped>\n.not-allowed {\n cursor: default;\n}\n</style>\n"],"names":["_sfc_main","props","formData","inject","blockParams","rows","ref","generateRows","operators","showOperatorColumn","computed","showValueColumn","inputContent","properties","getUniqueKeys","watch","newProperties","param","transformedRows","row","index","generateObjects","item","combined","set","key","handleIconClick","isComplete","removeRow","objects","groups","obj","group","lastRow","_hoisted_1","_openBlock","_createElementBlock","_Fragment","_renderList","$setup","_createBlock","_component_v_row","_createVNode","_component_v_col","_component_v_select","$event","_ctx","_component_v_text_field","_component_v_icon","_normalizeClass","_cache"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ System.register(["./main-hhWt7S1o.js","single-spa-vue"],(function(U,L){"use strict";var I,i,E,g,x,b,p,f,j,C,F,k,B,T,q,M,R,S,w;return{setters:[t=>{I=t._,i=t.r,E=t.c,g=t.o,x=t.a,b=t.b,p=t.w,f=t.d,j=t.l,C=t.e,F=t.F,k=t.i,B=t.u,T=t.h,q=t.m,M=t.t,R=t.k,S=t.p,w=t.q},null],execute:(function(){const t={props:["data","dynamicParams"],setup(D){const s=k("valid");s.value=!1;const{t:v}=B(),a=k("formData"),d=T(()=>D.dynamicParams.valuesType);Object.keys(a).length<=1&&(a.parameters=[{value:"",touchedValue:!1}]);const O=q({items:a.parameters.length>0?A(a.parameters):[{value:"",touchedValue:!1}]}),{items:o}=M(O);R(o,e=>{e[e.length-1].value&&e.push({value:"",touchedValue:!1}),a.parameters=P(),h(e),y(e)},{deep:!0});const h=e=>{e.length===1&&!e[0].value&&(e[0].touchedValue=!1)},y=e=>{const r=e.filter(l=>l.value),n=e.filter(l=>!l.value);s.value=r.length>0&&n.length<=1},_=()=>o.value.length===1,V=()=>o.value.filter(e=>!e.value).length>1,u=()=>[e=>_()&&!e||!_()&&V()&&!e?v("strings.value-is-required"):!0,e=>!_()&&e=="not valid"||V()&&e=="not valid"?v("strings.value-must-be-type")+" "+d.value:!0],m=(e,r,n)=>{try{S(e)===d.value?(w(e,n,r),s.value=!0):(r[n]=v("strings.not-valid"),s.value=!1)}catch(l){console.error("Error handling drop event: ",l)}},c=e=>{try{o.value.splice(e,1),a.parameters=P(o.value),h(o.value),y(o.value)}catch(r){console.error("Error removing item: ",r)}};function P(){const e=(r,n)=>({name:r,property:n,property2:"undefined",operator:"undefined",sourceexp:!0,bind:!0,custom:!0,value:""});return s.value=!0,o.value.flatMap((r,n)=>{const l=[];return r.value&&l.push(e("__item_"+n,r.value)),l})}function A(e){let r=[],n={value:"",touchedValue:!1};return e.forEach(l=>{l.name.startsWith("__item_")&&(n.value=l.property),n.value&&(r.push({...n}),n={value:"",touchedValue:!1})}),r.push({value:"",touchedValue:!1}),r}return{valuesType:d,onDrop:m,formData:a,items:o,removeItem:c,getValueRules:u,valid:s}}};function $(D,s,v,a,d,O){const o=i("v-text-field"),h=i("v-col"),y=i("v-btn"),_=i("v-row"),V=i("v-sheet");return g(!0),E(F,null,x(a.items,(u,m)=>(g(),b(V,{key:m},{default:p(()=>[f(_,{dense:""},{default:p(()=>[f(h,{cols:"10"},{default:p(()=>[f(o,{modelValue:u.value,"onUpdate:modelValue":c=>u.value=c,label:D.$t("labels.value"),variant:"outlined",density:"compact",rules:a.getValueRules(u),onFocus:c=>u.touchedValue=!0,onDragover:s[0]||(s[0]=j(()=>{},["prevent"])),onDrop:c=>a.onDrop(c,u,"value")},null,8,["modelValue","onUpdate:modelValue","label","rules","onFocus","onDrop"])]),_:2},1024),f(h,{cols:"2","text-center":""},{default:p(()=>[m<a.items.length-1?(g(),b(y,{key:0,class:"mt-n1",variant:"plain",icon:"mdi-delete",color:"secondary",onClick:c=>a.removeItem(m)},null,8,["onClick"])):C("",!0)]),_:2},1024)]),_:2},1024)]),_:2},1024))),128)}const N=U("default",I(t,[["render",$]]))})}}));
2
+ //# sourceMappingURL=FlexibleValueBlock-NBc8J-ed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlexibleValueBlock-NBc8J-ed.js","sources":["../../src/components/blocks/FlexibleValueBlock.vue"],"sourcesContent":["<template>\n <v-sheet v-for=\"(item, index) in items\" :key=\"index\">\n <v-row dense>\n <v-col cols=\"10\">\n <v-text-field\n v-model=\"item.value\"\n :label=\"$t('labels.value')\"\n variant=\"outlined\"\n density=\"compact\"\n :rules=\"getValueRules(item)\"\n @focus=\"item.touchedValue = true\"\n @dragover.prevent\n @drop=\"onDrop($event, item, 'value')\"\n ></v-text-field>\n </v-col>\n <v-col cols=\"2\" text-center>\n <v-btn\n v-if=\"index < items.length - 1\"\n class=\"mt-n1\"\n variant=\"plain\"\n icon=\"mdi-delete\"\n color=\"secondary\"\n @click=\"removeItem(index)\"\n ></v-btn>\n </v-col>\n </v-row>\n </v-sheet>\n</template>\n\n<script>\nimport { inject, toRefs, reactive, watch, computed } from \"vue\";\nimport { drop, checkDrop } from \"@/mixins/common-utils.js\";\nimport { useI18n } from \"vue-i18n\";\n\nexport default {\n props: [\"data\", \"dynamicParams\"],\n setup(props) {\n const valid = inject(\"valid\");\n valid.value = false;\n const { t } = useI18n();\n const formData = inject(\"formData\");\n const valuesType = computed(() => props.dynamicParams.valuesType);\n\n // Initialize parameters if they don't exist\n if (Object.keys(formData).length <= 1) {\n formData.parameters = [{ value: \"\", touchedValue: false }];\n }\n\n // Reactive state for the component\n const state = reactive({\n items:\n formData.parameters.length > 0\n ? revertToItems(formData.parameters)\n : [{ value: \"\", touchedValue: false }],\n });\n const { items } = toRefs(state);\n\n // Watch for changes in items and add a new empty row if needed\n watch(\n items,\n (newItems) => {\n const lastItem = newItems[newItems.length - 1];\n if (lastItem.value) {\n newItems.push({\n value: \"\",\n touchedValue: false,\n });\n }\n formData.parameters = breakAndEnrichItem(newItems);\n resetTouchedState(newItems);\n validateItems(newItems);\n },\n { deep: true },\n );\n\n // Reset touched state if there is only one empty row\n const resetTouchedState = (items) => {\n if (items.length === 1 && !items[0].value) {\n items[0].touchedValue = false;\n }\n };\n\n // Validate items based on the new rules\n const validateItems = (items) => {\n const nonEmptyItems = items.filter((item) => item.value);\n const emptyItems = items.filter((item) => !item.value);\n valid.value = nonEmptyItems.length > 0 && emptyItems.length <= 1;\n };\n\n // Check if there is only one item\n const isSingleItem = () => items.value.length === 1;\n\n // Check if there are multiple empty items\n const hasMultipleEmptyItems = () =>\n items.value.filter((item) => !item.value).length > 1;\n\n // Computed properties for validation rules\n const getValueRules = () => [\n (v) => {\n if (isSingleItem() && !v) {\n return t(\"strings.value-is-required\");\n }\n if (!isSingleItem() && hasMultipleEmptyItems() && !v) {\n return t(\"strings.value-is-required\");\n }\n return true;\n },\n (v) => {\n if (!isSingleItem() && v == \"not valid\") {\n return t(\"strings.value-must-be-type\") + \" \" + valuesType.value;\n }\n if (hasMultipleEmptyItems() && v == \"not valid\") {\n return t(\"strings.value-must-be-type\") + \" \" + valuesType.value;\n }\n return true;\n },\n ];\n\n // Handle drop event for drag-and-drop\n const onDrop = (event, item, targetName) => {\n try {\n const isValidDrop = checkDrop(event) === valuesType.value;\n\n if (isValidDrop) {\n drop(event, targetName, item);\n valid.value = true;\n } else {\n item[targetName] = t(\"strings.not-valid\");\n valid.value = false;\n }\n } catch (error) {\n console.error(\"Error handling drop event: \", error);\n }\n };\n\n // Remove a value pair\n const removeItem = (index) => {\n try {\n items.value.splice(index, 1);\n formData.parameters = breakAndEnrichItem(items.value);\n resetTouchedState(items.value);\n validateItems(items.value);\n } catch (error) {\n console.error(\"Error removing item: \", error);\n }\n };\n\n // Split an array of objects with value pairs\n // into an array of object pairs with a single property value\n function breakAndEnrichItem() {\n const createObject = (name, property) => ({\n name,\n property,\n property2: \"undefined\",\n operator: \"undefined\",\n sourceexp: true,\n bind: true,\n custom: true,\n value: \"\", // Inizializza la proprietΓ  value\n });\n valid.value = true;\n return items.value.flatMap((item, index) => {\n const objects = [];\n if (item.value) {\n objects.push(createObject(\"__item_\" + index, item.value));\n }\n return objects;\n });\n }\n\n // Transforms an array of objects with a single property into an array of objects with value pairs\n function revertToItems(parameters) {\n let items = [];\n let currentItem = {\n value: \"\",\n touchedValue: false,\n };\n\n parameters.forEach((param) => {\n if (param.name.startsWith(\"__item_\")) {\n currentItem.value = param.property;\n }\n\n // If value is set, push the current item and reset it\n if (currentItem.value) {\n items.push({ ...currentItem });\n currentItem = {\n value: \"\",\n touchedValue: false,\n };\n }\n });\n\n // Add an empty value pair at the end\n items.push({\n value: \"\",\n touchedValue: false,\n });\n return items;\n }\n\n return {\n valuesType,\n onDrop,\n formData,\n items,\n removeItem,\n getValueRules,\n valid,\n };\n },\n};\n</script>\n"],"names":["_sfc_main","props","valid","inject","t","useI18n","formData","valuesType","computed","state","reactive","revertToItems","items","toRefs","watch","newItems","breakAndEnrichItem","resetTouchedState","validateItems","nonEmptyItems","item","emptyItems","isSingleItem","hasMultipleEmptyItems","getValueRules","v","onDrop","event","targetName","checkDrop","drop","error","removeItem","index","createObject","name","property","objects","parameters","currentItem","param","_openBlock","_createElementBlock","_Fragment","_renderList","$setup","_createBlock","_component_v_sheet","_createVNode","_component_v_row","_component_v_col","_component_v_text_field","$event","_ctx","_component_v_btn"],"mappings":"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"}