From 2dd6d09d5163100aec4794e58cabff0529a0f252 Mon Sep 17 00:00:00 2001 From: Thijn Date: Thu, 17 Oct 2024 13:53:53 +0200 Subject: [PATCH 1/3] fixed typo in passThrough --- docs/schema/Mapping.json | 2 +- lib/Db/Mapping.php | 6 +++--- lib/Migration/Version0Date20240826193657.php | 2 +- lib/Service/MappingService.php | 4 ++-- src/entities/mapping/mapping.mock.ts | 4 ++-- src/entities/mapping/mapping.ts | 4 ++-- src/entities/mapping/mapping.types.ts | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/schema/Mapping.json b/docs/schema/Mapping.json index 44a1020..c36ee06 100644 --- a/docs/schema/Mapping.json +++ b/docs/schema/Mapping.json @@ -39,7 +39,7 @@ "type": ["array", "null"], "description": "The cast of this mapping object." }, - "passTrough": { + "passThrough": { "type": ["boolean", "null"], "default": true, "description": "The passThrough of this mapping object." diff --git a/lib/Db/Mapping.php b/lib/Db/Mapping.php index d32dcfc..a6bf62b 100644 --- a/lib/Db/Mapping.php +++ b/lib/Db/Mapping.php @@ -16,7 +16,7 @@ class Mapping extends Entity implements JsonSerializable protected ?array $mapping = null; protected ?array $unset = null; protected ?array $cast = null; - protected ?bool $passTrough = null; + protected ?bool $passThrough = null; protected ?DateTime $dateCreated = null; protected ?DateTime $dateModified = null; @@ -29,7 +29,7 @@ public function __construct() { $this->addType('mapping', 'json'); $this->addType('unset', 'json'); $this->addType('cast', 'json'); - $this->addType('passTrough', 'boolean'); + $this->addType('passThrough', 'boolean'); $this->addType('dateCreated', 'datetime'); $this->addType('dateModified', 'datetime'); } @@ -76,7 +76,7 @@ public function jsonSerialize(): array 'mapping' => $this->mapping, 'unset' => $this->unset, 'cast' => $this->cast, - 'passTrough' => $this->passTrough, + 'passThrough' => $this->passThrough, 'dateCreated' => isset($this->dateCreated) ? $this->dateCreated->format('c') : null, 'dateModified' => isset($this->dateModified) ? $this->dateModified->format('c') : null, ]; diff --git a/lib/Migration/Version0Date20240826193657.php b/lib/Migration/Version0Date20240826193657.php index 752d728..e9b4b8f 100644 --- a/lib/Migration/Version0Date20240826193657.php +++ b/lib/Migration/Version0Date20240826193657.php @@ -102,7 +102,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt $table->addColumn('mapping', Types::TEXT, ['notnull' => false]); $table->addColumn('unset', Types::TEXT, ['notnull' => false]); $table->addColumn('cast', Types::TEXT, ['notnull' => false]); - $table->addColumn('pass_trough', Types::BOOLEAN, ['notnull' => false]); + $table->addColumn('pass_through', Types::BOOLEAN, ['notnull' => false]); $table->addColumn('date_created', Types::DATETIME, ['notnull' => true, 'default' => 'CURRENT_TIMESTAMP']); $table->addColumn('date_modified', Types::DATETIME, ['notnull' => true, 'default' => 'CURRENT_TIMESTAMP']); $table->setPrimaryKey(['id']); diff --git a/lib/Service/MappingService.php b/lib/Service/MappingService.php index 4202902..81dfba8 100644 --- a/lib/Service/MappingService.php +++ b/lib/Service/MappingService.php @@ -107,7 +107,7 @@ public function mapping(Mapping $mappingObject, array $input, bool $list = false // Determine pass trough. // Let's get the dot array based on https://github.com/adbario/php-dot-notation. - if ($mappingObject->getPassTrough()) { + if ($mappingObject->getPassThrough()) { $dotArray = new Dot($input); // @todo: error loging // isset($this->style) === true && $this->style->info('Mapping *with* pass trough'); @@ -188,7 +188,7 @@ public function mapping(Mapping $mappingObject, array $input, bool $list = false [ 'input' => $input, 'output' => $output, - 'passTrough' => $mappingObject->getPassTrough(), + 'passThrough' => $mappingObject->getPassThrough(), 'mapping' => $mappingObject->getMapping(), ] ); diff --git a/src/entities/mapping/mapping.mock.ts b/src/entities/mapping/mapping.mock.ts index e6a8498..c906179 100644 --- a/src/entities/mapping/mapping.mock.ts +++ b/src/entities/mapping/mapping.mock.ts @@ -12,7 +12,7 @@ export const mockMappingData = (): TMapping[] => [ { source: 'lastName', target: 'family_name' }, { source: 'email', target: 'email_address' }, ], - passTrough: true, + passThrough: true, }, { id: '4c3edd34-a90d-4d2a-8894-adb5836ecde8', @@ -24,7 +24,7 @@ export const mockMappingData = (): TMapping[] => [ { source: 'productPrice', target: 'price' }, { source: 'productDescription', target: 'description' }, ], - passTrough: false, + passThrough: false, unset: ['internal_id', 'created_by'], cast: [ { field: 'price', type: 'float' }, diff --git a/src/entities/mapping/mapping.ts b/src/entities/mapping/mapping.ts index 3a27cb3..8d48ef3 100644 --- a/src/entities/mapping/mapping.ts +++ b/src/entities/mapping/mapping.ts @@ -12,7 +12,7 @@ export class Mapping implements TMapping { public mapping: any[] public unset: any[] | null public cast: any[] | null - public passTrough: boolean | null + public passThrough: boolean | null public dateCreated: string | null public dateModified: string | null @@ -25,7 +25,7 @@ export class Mapping implements TMapping { this.mapping = mapping.mapping || [] this.unset = mapping.unset || null this.cast = mapping.cast || null - this.passTrough = mapping.passTrough ?? true + this.passThrough = mapping.passThrough ?? true this.dateCreated = mapping.dateCreated || null this.dateModified = mapping.dateModified || null } diff --git a/src/entities/mapping/mapping.types.ts b/src/entities/mapping/mapping.types.ts index 773cf79..9d8ea32 100644 --- a/src/entities/mapping/mapping.types.ts +++ b/src/entities/mapping/mapping.types.ts @@ -8,7 +8,7 @@ export type TMapping = { mapping: any[] unset?: any[] | null cast?: any[] | null - passTrough?: boolean | null + passThrough?: boolean | null dateCreated?: string | null dateModified?: string | null } From cb6a46fa10993903ed159efd88dd42cfe9f079fb Mon Sep 17 00:00:00 2001 From: Thijn Date: Thu, 17 Oct 2024 15:13:42 +0200 Subject: [PATCH 2/3] first attempt at mapping docs --- src/entities/mapping/mapping.mock.ts | 14 +++++- src/entities/mapping/mapping.ts | 44 ++++++++++------- src/entities/mapping/mapping.types.ts | 17 ++++--- src/modals/Mapping/EditMapping.vue | 71 ++++++++++++++++++--------- src/services/openLink.js | 3 ++ src/store/modules/mapping.js | 34 +++++-------- 6 files changed, 111 insertions(+), 72 deletions(-) create mode 100644 src/services/openLink.js diff --git a/src/entities/mapping/mapping.mock.ts b/src/entities/mapping/mapping.mock.ts index c906179..b4f9bc7 100644 --- a/src/entities/mapping/mapping.mock.ts +++ b/src/entities/mapping/mapping.mock.ts @@ -3,7 +3,8 @@ import { TMapping } from './mapping.types' export const mockMappingData = (): TMapping[] => [ { - id: '5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f', + id: 1, + uuid: '5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f', name: 'User Data Mapping', version: '1.0.0', description: 'Maps user data from source to target system', @@ -13,9 +14,15 @@ export const mockMappingData = (): TMapping[] => [ { source: 'email', target: 'email_address' }, ], passThrough: true, + reference: '', + unset: [], + cast: [], + dateCreated: '', + dateModified: '', }, { - id: '4c3edd34-a90d-4d2a-8894-adb5836ecde8', + id: 2, + uuid: '5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f', name: 'Product Mapping', version: '1.1.0', description: 'Maps product data between systems', @@ -30,6 +37,9 @@ export const mockMappingData = (): TMapping[] => [ { field: 'price', type: 'float' }, { field: 'inStock', type: 'boolean' }, ], + reference: '', + dateCreated: '', + dateModified: '', }, ] diff --git a/src/entities/mapping/mapping.ts b/src/entities/mapping/mapping.ts index 8d48ef3..8c7bc6c 100644 --- a/src/entities/mapping/mapping.ts +++ b/src/entities/mapping/mapping.ts @@ -4,38 +4,48 @@ import { TMapping } from './mapping.types' export class Mapping implements TMapping { - public id: string - public reference: string | null + public id: number + public uuid: string + public reference: string public version: string public name: string - public description: string | null + public description: string public mapping: any[] - public unset: any[] | null - public cast: any[] | null - public passThrough: boolean | null - public dateCreated: string | null - public dateModified: string | null + public unset: any[] + public cast: any[] + public passThrough: boolean + public dateCreated: string + public dateModified: string constructor(mapping: TMapping) { - this.id = mapping.id || '' - this.reference = mapping.reference || null + this.id = mapping.id || null + this.uuid = mapping.uuid || null + this.reference = mapping.reference || '' this.version = mapping.version || '0.0.0' this.name = mapping.name || '' - this.description = mapping.description || null + this.description = mapping.description || '' this.mapping = mapping.mapping || [] - this.unset = mapping.unset || null - this.cast = mapping.cast || null + this.unset = mapping.unset || [] + this.cast = mapping.cast || [] this.passThrough = mapping.passThrough ?? true - this.dateCreated = mapping.dateCreated || null - this.dateModified = mapping.dateModified || null + this.dateCreated = mapping.dateCreated || '' + this.dateModified = mapping.dateModified || '' } public validate(): SafeParseReturnType { const schema = z.object({ - id: z.string().uuid(), + id: z.number().or(z.null()), + uuid: z.string().uuid().max(36).or(z.null()), + reference: z.string().max(255), + version: z.string().max(255), name: z.string().max(255), - version: z.string(), + description: z.string(), mapping: z.array(z.any()), + unset: z.array(z.any()), + cast: z.array(z.any()), + passThrough: z.boolean(), + dateCreated: z.string().or(z.literal('')), + dateModified: z.string().or(z.literal('')), }) return schema.safeParse({ ...this }) diff --git a/src/entities/mapping/mapping.types.ts b/src/entities/mapping/mapping.types.ts index 9d8ea32..675c3c5 100644 --- a/src/entities/mapping/mapping.types.ts +++ b/src/entities/mapping/mapping.types.ts @@ -1,14 +1,15 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ export type TMapping = { - id?: string - reference?: string | null + id: number + uuid: string + reference: string version: string name: string - description?: string | null + description: string mapping: any[] - unset?: any[] | null - cast?: any[] | null - passThrough?: boolean | null - dateCreated?: string | null - dateModified?: string | null + unset: any[] + cast: any[] + passThrough: boolean + dateCreated: string + dateModified: string } diff --git a/src/modals/Mapping/EditMapping.vue b/src/modals/Mapping/EditMapping.vue index d1e4a37..93c9660 100644 --- a/src/modals/Mapping/EditMapping.vue +++ b/src/modals/Mapping/EditMapping.vue @@ -9,6 +9,7 @@ import { mappingStore, navigationStore } from '../../store/store.js' @close="closeModal">

Mapping {{ mappingStore.mappingItem?.id ? 'Edit' : 'Add' }}

+

Mapping successfully added

@@ -27,20 +28,32 @@ import { mappingStore, navigationStore } from '../../store/store.js' id="description" label="Description" :value.sync="mappingItem.description" /> + + + Pass Through +
- - - Save - +
+ + + Save + + + + Documentation + +
@@ -53,8 +66,12 @@ import { NcNoteCard, NcTextField, NcTextArea, + NcCheckboxRadioSwitch, } from '@nextcloud/vue' import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue' +import BookOpenVariant from 'vue-material-design-icons/BookOpenVariant.vue' + +import openLink from '../../services/openLink.js' export default { name: 'EditMapping', @@ -65,6 +82,7 @@ export default { NcNoteCard, NcTextField, NcTextArea, + NcCheckboxRadioSwitch, // Icons ContentSaveOutline, }, @@ -73,8 +91,9 @@ export default { mappingItem: { name: '', description: '', + passThrough: true, }, - success: false, + success: null, loading: false, error: false, hasUpdated: false, @@ -101,7 +120,7 @@ export default { closeModal() { navigationStore.setModal(false) clearTimeout(this.closeTimeoutFunc) - this.success = false + this.success = null this.loading = false this.error = false this.hasUpdated = false @@ -109,22 +128,30 @@ export default { id: null, name: '', description: '', + passThrough: true, } }, async editMapping() { this.loading = true - try { - await mappingStore.saveMapping(this.mappingItem) - // Close modal or show success message - this.success = true - this.loading = false + + mappingStore.saveMapping({ + ...this.mappingItem, + }).then(({ response }) => { + this.success = response.ok this.closeTimeoutFunc = setTimeout(this.closeModal, 2000) - } catch (error) { - this.loading = false - this.success = false + }).catch((error) => { this.error = error.message || 'An error occurred while saving the mapping' - } + }).finally(() => { + this.loading = false + }) }, }, } + + diff --git a/src/services/openLink.js b/src/services/openLink.js new file mode 100644 index 0000000..7e497ef --- /dev/null +++ b/src/services/openLink.js @@ -0,0 +1,3 @@ +export default function openLink(url, target = '') { + window.open(url, target) +} diff --git a/src/store/modules/mapping.js b/src/store/modules/mapping.js index 6f46571..4c6fb4a 100644 --- a/src/store/modules/mapping.js +++ b/src/store/modules/mapping.js @@ -91,7 +91,7 @@ export const useMappingStore = defineStore( }) }, // Create or save a mapping from store - saveMapping(mappingItem) { + async saveMapping(mappingItem) { if (!mappingItem) { throw new Error('No mapping item to save') } @@ -104,37 +104,25 @@ export const useMappingStore = defineStore( : `/index.php/apps/openconnector/api/mappings/${mappingItem.id}` const method = isNewMapping ? 'POST' : 'PUT' - // Create a copy of the mapping item and remove empty properties - const mappingToSave = { ...mappingItem } - Object.keys(mappingToSave).forEach(key => { - if (mappingToSave[key] === '' || (Array.isArray(mappingToSave[key]) && !mappingToSave[key].length) || key === 'dateCreated' || key === 'dateModified') { - delete mappingToSave[key] - } - }) - - return fetch( + const response = await fetch( endpoint, { method, headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify(mappingToSave), + body: JSON.stringify(mappingItem), }, ) - .then((response) => response.json()) - .then((data) => { - this.setMappingItem(data) - console.log('Mapping saved') - // Refresh the mapping list - return this.refreshMappingList() - }) - .catch((err) => { - console.error('Error saving mapping:', err) - throw err - }) - }, + const data = await response.json() + const entity = new Mapping(data) + + this.setMappingItem(entity) + this.refreshMappingList() + + return { response, data, entity } + }, }, }, ) From e6ca1486c63885f45db61077dc756261be3240a2 Mon Sep 17 00:00:00 2001 From: Thijn Date: Thu, 17 Oct 2024 15:30:28 +0200 Subject: [PATCH 3/3] finished mapping passthrough --- src/entities/mapping/mapping.ts | 2 +- src/main.js | 2 ++ src/modals/Mapping/EditMapping.vue | 36 +++++++++++++++++------------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/entities/mapping/mapping.ts b/src/entities/mapping/mapping.ts index 8c7bc6c..c951d08 100644 --- a/src/entities/mapping/mapping.ts +++ b/src/entities/mapping/mapping.ts @@ -27,7 +27,7 @@ export class Mapping implements TMapping { this.mapping = mapping.mapping || [] this.unset = mapping.unset || [] this.cast = mapping.cast || [] - this.passThrough = mapping.passThrough ?? true + this.passThrough = mapping.passThrough ?? false this.dateCreated = mapping.dateCreated || '' this.dateModified = mapping.dateModified || '' } diff --git a/src/main.js b/src/main.js index 11977c1..1784cc2 100644 --- a/src/main.js +++ b/src/main.js @@ -1,10 +1,12 @@ import Vue from 'vue' import { PiniaVuePlugin } from 'pinia' +import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js' import pinia from './pinia.js' import App from './App.vue' Vue.mixin({ methods: { t, n } }) Vue.use(PiniaVuePlugin) +Vue.directive('tooltip', Tooltip) new Vue( { diff --git a/src/modals/Mapping/EditMapping.vue b/src/modals/Mapping/EditMapping.vue index 93c9660..118d976 100644 --- a/src/modals/Mapping/EditMapping.vue +++ b/src/modals/Mapping/EditMapping.vue @@ -29,10 +29,17 @@ import { mappingStore, navigationStore } from '../../store/store.js' label="Description" :value.sync="mappingItem.description" /> - - Pass Through - + + + Pass Through + + + + + @@ -46,13 +53,6 @@ import { mappingStore, navigationStore } from '../../store/store.js' Save - - - Documentation - @@ -69,9 +69,7 @@ import { NcCheckboxRadioSwitch, } from '@nextcloud/vue' import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue' -import BookOpenVariant from 'vue-material-design-icons/BookOpenVariant.vue' - -import openLink from '../../services/openLink.js' +import HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue' export default { name: 'EditMapping', @@ -91,7 +89,7 @@ export default { mappingItem: { name: '', description: '', - passThrough: true, + passThrough: false, }, success: null, loading: false, @@ -128,7 +126,7 @@ export default { id: null, name: '', description: '', - passThrough: true, + passThrough: false, } }, async editMapping() { @@ -154,4 +152,10 @@ export default { display: flex; gap: 10px; } + +.flex-container { + display: flex; + align-items: center; + gap: 10px; +}