From 142ae0db6107dad8919079ad38c9c5f0b4d9c5da Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Fri, 9 Aug 2024 16:22:35 +0200 Subject: [PATCH 01/52] Add source to metadata --- lib/Controller/MetaDataController.php | 30 ++++++++- lib/Db/MetaData.php | 6 +- lib/Migration/Version6Date20240809141351.php | 69 ++++++++++++++++++++ 3 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 lib/Migration/Version6Date20240809141351.php diff --git a/lib/Controller/MetaDataController.php b/lib/Controller/MetaDataController.php index 282ac304..fb72f8a7 100644 --- a/lib/Controller/MetaDataController.php +++ b/lib/Controller/MetaDataController.php @@ -11,6 +11,7 @@ use OCP\AppFramework\Http\JSONResponse; use OCP\IAppConfig; use OCP\IRequest; +use OCP\IURLGenerator; class MetaDataController extends Controller { @@ -43,6 +44,7 @@ public function page(?string $getParameter) } /** + * @PublicPage * @NoAdminRequired * @NoCSRFRequired */ @@ -77,6 +79,7 @@ public function index(ObjectService $objectService, SearchService $searchService } /** + * @PublicPage * @NoAdminRequired * @NoCSRFRequired */ @@ -107,13 +110,15 @@ public function show(string|int $id, ObjectService $objectService): JSONResponse * @NoAdminRequired * @NoCSRFRequired */ - public function create(ObjectService $objectService): JSONResponse + public function create(ObjectService $objectService, IURLGenerator $urlGenerator): JSONResponse { $data = $this->request->getParams(); // Remove fields we should never post unset($data['id']); + + foreach($data as $key => $value) { if(str_starts_with($key, '_')) { unset($data[$key]); @@ -123,7 +128,18 @@ public function create(ObjectService $objectService): JSONResponse if($this->config->hasKey($this->appName, 'mongoStorage') === false || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' ) { - return new JSONResponse($this->metaDataMapper->createFromArray(object: $data)); + $object = $this->metaDataMapper->createFromArray(object: $data); + + $id = $object->getId(); + + if($object->getSource() === null) { + $source = $urlGenerator->getAbsoluteURL($urlGenerator->linkToRoute(routeName:"opencatalogi.metadata.show", arguments: ['id' => $id])); + $object->setSource($source); + $this->metaDataMapper->update($object); + } + + + return new JSONResponse($object); } $dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation'); $dbConfig['headers']['api-key'] = $this->config->getValueString(app: $this->appName, key: 'mongodbKey'); @@ -136,6 +152,14 @@ public function create(ObjectService $objectService): JSONResponse config: $dbConfig ); + if(isset($data['source']) === false || $data['source'] === null) { + $returnData['source'] = $urlGenerator->getAbsoluteURL($urlGenerator->linkToRoute(routeName:"opencatalogi.metadata.show", arguments: ['id' => $returnData['id']])); + $returnData = $objectService->saveObject( + data: $data, + config: $dbConfig + ); + } + // get post from requests return new JSONResponse($returnData); } @@ -149,7 +173,7 @@ public function update(string|int $id, ObjectService $objectService): JSONRespon $data = $this->request->getParams(); // Remove fields we should never post - unset($data['id']); + unset($data['id'],$data['source']); foreach($data as $key => $value) { if(str_starts_with($key, '_')) { unset($data[$key]); diff --git a/lib/Db/MetaData.php b/lib/Db/MetaData.php index 759cf14c..1f7d3433 100644 --- a/lib/Db/MetaData.php +++ b/lib/Db/MetaData.php @@ -12,8 +12,9 @@ class MetaData extends Entity implements JsonSerializable protected ?string $title = null; protected ?string $version = null; protected ?string $description = null; - protected ?array $required = []; - protected ?array $properties = []; + protected ?array $required = []; + protected ?array $properties = []; + protected ?string $source = null; public function __construct() { $this->addType(fieldName: 'title', type: 'string'); @@ -63,6 +64,7 @@ public function jsonSerialize(): array 'description' => $this->description, 'required' => $this->required, 'properties' => $this->properties, + 'source' => $this->source, ]; $jsonFields = $this->getJsonFields(); diff --git a/lib/Migration/Version6Date20240809141351.php b/lib/Migration/Version6Date20240809141351.php new file mode 100644 index 00000000..8f8563ee --- /dev/null +++ b/lib/Migration/Version6Date20240809141351.php @@ -0,0 +1,69 @@ +hasTable(tableName: 'metadata') === true) { + $table = $schema->getTable(tableName: 'metadata'); + + if($table->hasColumn(name: 'source') === false) { + $table->addColumn( + name: 'source', + typeName: Types::STRING, + options: [ + 'notNull' => false, + 'default' => null + ]); + $output->info('source should be added to metadata'); + } + + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} From fdc6aa707a44774f92561c5a270ddc023a915dc6 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 13 Aug 2024 11:13:40 +0200 Subject: [PATCH 02/52] Add validation service --- lib/Controller/PublicationsController.php | 5 +- lib/Service/ValidationService.php | 92 +++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 lib/Service/ValidationService.php diff --git a/lib/Controller/PublicationsController.php b/lib/Controller/PublicationsController.php index 3111b16e..d4983142 100644 --- a/lib/Controller/PublicationsController.php +++ b/lib/Controller/PublicationsController.php @@ -9,6 +9,7 @@ use OCA\OpenCatalogi\Service\ElasticSearchService; use OCA\OpenCatalogi\Service\ObjectService; use OCA\OpenCatalogi\Service\SearchService; +use OCA\OpenCatalogi\Service\ValidationService; use OCP\AppFramework\Controller; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http\TemplateResponse; @@ -202,7 +203,7 @@ public function show(string|int $id, ObjectService $objectService): JSONResponse * @NoAdminRequired * @NoCSRFRequired */ - public function create(ObjectService $objectService, ElasticSearchService $elasticSearchService): JSONResponse + public function create(ObjectService $objectService, ElasticSearchService $elasticSearchService, ValidationService $validationService): JSONResponse { $data = $this->request->getParams(); @@ -214,6 +215,8 @@ public function create(ObjectService $objectService, ElasticSearchService $elast } } + $data = $validationService->validatePublication($data); + if($this->config->hasKey($this->appName, 'mongoStorage') === false || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' ) { diff --git a/lib/Service/ValidationService.php b/lib/Service/ValidationService.php new file mode 100644 index 00000000..19269e30 --- /dev/null +++ b/lib/Service/ValidationService.php @@ -0,0 +1,92 @@ +appName = 'opencatalogi'; + + $this->mongodbConfig = [ + 'base_uri' => $this->config->getValueString(app: $this->appName, key: 'mongodbLocation'), + 'headers' => ['api-key' => $this->config->getValueString(app: $this->appName, key: 'mongodbKey')], + 'mongodbCluster' => $this->config->getValueString(app: $this->appName, key:'mongodbCluster') + ]; + + } + + /** + * @return array The mongodb config. + */ + public function getMongodbConfig(): array + { + return $this->mongodbConfig; + } + + /** + * Fetches a catalog from either the local database or mongodb + * + * @param string $id The id of the catalog to be fetched. + * @return array The JSON Serialised catalog. + * + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function getCatalog (string $id): array + { + if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false + || $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1' + ) { + $filter = ['id' => $id, '_schema' => 'catalog']; + + return $this->objectService->findObject(filters: $filter, config: $this->getMongodbConfig()); + } + + return $this->catalogMapper->find(id: $id)->jsonSerialize(); + } + + /** + * Validates a publication against the rules set for the publication. + * + * @param array $publication The publication to be validated. + * @return array The publication after it has been validated. + * + * @throws OCSBadRequestException Thrown if the object does not validate + */ + public function validatePublication(array $publication): array + { + $catalogId = $publication['catalog']; + $metadata = $publication['metadata']; + + $catalog = $this->getCatalog($catalogId); + + if(in_array(needle: $metadata, haystack: $catalog['metadata']) === false) { + throw new OCSBadRequestException(message: 'Given metadata object not present in catalog'); + } + + return $publication; + } + +} From 9fd944727272307801f44b3965e2ead330269519 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 13 Aug 2024 11:53:15 +0200 Subject: [PATCH 03/52] Fixes from local tests --- lib/Controller/PublicationsController.php | 7 ++++++- lib/Service/ValidationService.php | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/Controller/PublicationsController.php b/lib/Controller/PublicationsController.php index d4983142..7c86e908 100644 --- a/lib/Controller/PublicationsController.php +++ b/lib/Controller/PublicationsController.php @@ -14,6 +14,7 @@ use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\IAppConfig; use OCP\IRequest; use Symfony\Component\Uid\Uuid; @@ -215,7 +216,11 @@ public function create(ObjectService $objectService, ElasticSearchService $elast } } - $data = $validationService->validatePublication($data); + try { + $data = $validationService->validatePublication($data); + } catch (OCSBadRequestException $exception) { + return new JSONResponse(data: ['message' => $exception->getMessage()], statusCode: 400); + } if($this->config->hasKey($this->appName, 'mongoStorage') === false || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' diff --git a/lib/Service/ValidationService.php b/lib/Service/ValidationService.php index 19269e30..8f68ff69 100644 --- a/lib/Service/ValidationService.php +++ b/lib/Service/ValidationService.php @@ -56,8 +56,8 @@ public function getMongodbConfig(): array */ public function getCatalog (string $id): array { - if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false - || $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1' + if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') !== false + || $this->config->getValueString(app: $this->appName, key: 'mongoStorage') === '1' ) { $filter = ['id' => $id, '_schema' => 'catalog']; @@ -77,7 +77,7 @@ public function getCatalog (string $id): array */ public function validatePublication(array $publication): array { - $catalogId = $publication['catalog']; + $catalogId = $publication['catalogi']; $metadata = $publication['metadata']; $catalog = $this->getCatalog($catalogId); From 8a8d3bf0f5591fa7f5da3c58364f568925cfa6b5 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 14 Aug 2024 16:33:00 +0200 Subject: [PATCH 04/52] Updates on listing and metadata --- lib/Db/Listing.php | 26 ++++++++++++++------------ lib/Db/MetaData.php | 1 + lib/Service/ValidationService.php | 6 +++++- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/Db/Listing.php b/lib/Db/Listing.php index a26a5a48..a617ef92 100644 --- a/lib/Db/Listing.php +++ b/lib/Db/Listing.php @@ -9,19 +9,20 @@ class Listing extends Entity implements JsonSerializable { - protected ?string $title = null; - protected ?string $reference = null; - protected ?string $summary = null; - protected ?string $description = null; - protected ?string $search = null; - protected ?string $directory = null; - protected ?string $metadata = null; - protected ?string $catalogId = null; - protected ?string $status = null; + protected ?string $title = null; + protected ?string $reference = null; + protected ?string $summary = null; + protected ?string $description = null; + protected ?string $search = null; + protected ?string $directory = null; + protected ?string $metadata = null; + protected ?string $catalogId = null; + protected ?string $status = null; + protected ?int $statusCode = null; protected ?DateTime $lastSync = null; - protected ?bool $default = false; - protected ?bool $available = false; - protected ?string $organisation = null; + protected ?bool $default = false; + protected ?bool $available = false; + protected ?string $organisation = null; public function __construct() { $this->addType(fieldName: 'title', type: 'string'); @@ -32,6 +33,7 @@ public function __construct() { $this->addType(fieldName: 'metadata', type: 'string'); $this->addType(fieldName: 'catalogId', type: 'string'); $this->addType(fieldName: 'status', type: 'string'); + $this->addType(fieldName: 'statusCode', type: 'integer'); $this->addType(fieldName: 'lastSync', type: 'datetime'); $this->addType(fieldName: 'default', type: 'boolean'); $this->addType(fieldName: 'available', type: 'boolean'); diff --git a/lib/Db/MetaData.php b/lib/Db/MetaData.php index 1f7d3433..206d0a4d 100644 --- a/lib/Db/MetaData.php +++ b/lib/Db/MetaData.php @@ -14,6 +14,7 @@ class MetaData extends Entity implements JsonSerializable protected ?string $description = null; protected ?array $required = []; protected ?array $properties = []; + protected ?array $archive = []; protected ?string $source = null; public function __construct() { diff --git a/lib/Service/ValidationService.php b/lib/Service/ValidationService.php index 8f68ff69..66a6bbec 100644 --- a/lib/Service/ValidationService.php +++ b/lib/Service/ValidationService.php @@ -78,14 +78,18 @@ public function getCatalog (string $id): array public function validatePublication(array $publication): array { $catalogId = $publication['catalogi']; - $metadata = $publication['metadata']; + $metadata = $publication['metaData']; $catalog = $this->getCatalog($catalogId); +// var_dump($catalog['metadata'], $metadata, in_array(needle: $metadata, haystack: $catalog['metadata'])); + if(in_array(needle: $metadata, haystack: $catalog['metadata']) === false) { throw new OCSBadRequestException(message: 'Given metadata object not present in catalog'); } +// var_dump($publication); + return $publication; } From b9cf59ab27d223f59d59992cf3a32080fe6e8077 Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 15 Aug 2024 15:02:31 +0200 Subject: [PATCH 05/52] WIP: copy listing metadata --- lib/Db/Listing.php | 8 +- lib/Db/ListingMapper.php | 34 +++--- lib/Migration/Version6Date20240815105059.php | 82 ++++++++++++++ lib/Service/DirectoryService.php | 2 +- .../catalogiMetadata/AddCatalogiMetadata.vue | 12 ++- src/modals/metaData/AddMetaDataModal.vue | 6 ++ src/modals/metaData/EditMetaDataModal.vue | 1 + .../publication/AddPublicationModal.vue | 1 + src/sidebars/SideBars.vue | 4 +- src/sidebars/directory/DirectorySideBar.vue | 102 +++++++++++++++++- src/store/modules/directory.js | 2 +- src/views/publications/PublicationDetail.vue | 4 + 12 files changed, 230 insertions(+), 28 deletions(-) create mode 100644 lib/Migration/Version6Date20240815105059.php diff --git a/lib/Db/Listing.php b/lib/Db/Listing.php index a26a5a48..810d918d 100644 --- a/lib/Db/Listing.php +++ b/lib/Db/Listing.php @@ -15,7 +15,7 @@ class Listing extends Entity implements JsonSerializable protected ?string $description = null; protected ?string $search = null; protected ?string $directory = null; - protected ?string $metadata = null; + protected ?array $metadata = null; protected ?string $catalogId = null; protected ?string $status = null; protected ?DateTime $lastSync = null; @@ -29,7 +29,7 @@ public function __construct() { $this->addType(fieldName: 'description', type: 'string'); $this->addType(fieldName: 'search', type: 'string'); $this->addType(fieldName: 'directory', type: 'string'); - $this->addType(fieldName: 'metadata', type: 'string'); + $this->addType(fieldName: 'metadata', type: 'json'); $this->addType(fieldName: 'catalogId', type: 'string'); $this->addType(fieldName: 'status', type: 'string'); $this->addType(fieldName: 'lastSync', type: 'datetime'); @@ -51,6 +51,10 @@ public function hydrate(array $object): self { $jsonFields = $this->getJsonFields(); + if(isset($object['metadata']) === false) { + $object['metadata'] = []; + } + foreach($object as $key => $value) { if (in_array($key, $jsonFields) === true && $value === []) { $value = null; diff --git a/lib/Db/ListingMapper.php b/lib/Db/ListingMapper.php index a97a4730..95ac50e6 100644 --- a/lib/Db/ListingMapper.php +++ b/lib/Db/ListingMapper.php @@ -56,7 +56,7 @@ protected function mapRowToEntityCustom(array $row): Entity { } } - $row['organisation'] = $organisationIsEmpty === true ? null : Organisation::fromRow($organisationData); + // $row['organisation'] = $organisationIsEmpty === true ? null : Organisation::fromRow($organisationData); return \call_user_func($this->entityClass .'::fromRow', $row); } @@ -86,25 +86,25 @@ protected function findEntitiesCustom(IQueryBuilder $query): array { public function findAll(?int $limit = null, ?int $offset = null, ?array $filters = [], ?array $searchConditions = [], ?array $searchParams = []): array { $qb = $this->db->getQueryBuilder(); - - $qb->select( - 'l.*', - 'o.id AS organisation_id', - 'o.title AS organisation_title', - 'o.summary AS organisation_summary', - 'o.description AS organisation_description', - 'o.image AS organisation_image', - 'o.oin AS organisation_oin', - 'o.tooi AS organisation_tooi', - 'o.rsin AS organisation_rsin', - 'o.pki AS organisation_pki' + + $qb->select('*' + // 'l.*', + // 'o.id AS organisation_id', + // 'o.title AS organisation_title', + // 'o.summary AS organisation_summary', + // 'o.description AS organisation_description', + // 'o.image AS organisation_image', + // 'o.oin AS organisation_oin', + // 'o.tooi AS organisation_tooi', + // 'o.rsin AS organisation_rsin', + // 'o.pki AS organisation_pki' ) ->from('listings', 'l') - ->leftJoin('l', 'organizations', 'o', 'l.organisation = o.id') + // ->leftJoin('l', 'organizations', 'o', 'l.organisation = o.id') ->setMaxResults($limit) ->setFirstResult($offset); - + // Apply filters foreach ($filters as $filter => $value) { if ($value === 'IS NOT NULL') { @@ -115,7 +115,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters $qb->andWhere($qb->expr()->eq($filter, $qb->createNamedParameter($value))); } } - + // Apply search conditions if (!empty($searchConditions)) { $qb->andWhere('(' . implode(' OR ', $searchConditions) . ')'); @@ -123,7 +123,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters $qb->setParameter($param, $value); } } - + // Use the existing findEntities method to fetch and map the results return $this->findEntitiesCustom($qb); } diff --git a/lib/Migration/Version6Date20240815105059.php b/lib/Migration/Version6Date20240815105059.php new file mode 100644 index 00000000..44c909a4 --- /dev/null +++ b/lib/Migration/Version6Date20240815105059.php @@ -0,0 +1,82 @@ + + * + * FIXME @author Your name + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\OpenCatalogi\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; +use OCP\DB\Types; + +/** + * FIXME Auto-generated migration step: Please modify to your needs! + */ +class Version6Date20240815105059 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + $schema = $schemaClosure(); + $table = $schema->getTable('listings'); + + if ($table->hasColumn('metadata')) { + $table->dropColumn('metadata'); + } + + $table->addColumn( + name: 'metadata', + typeName: Types::JSON, + options: [ + 'notNull' => false, + 'default' => 'a:0:{}' + ]); + + $output->info("Added 'metadata' column as JSON type with a default value of an empty array."); + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} diff --git a/lib/Service/DirectoryService.php b/lib/Service/DirectoryService.php index 4de3e99b..3f0b6372 100644 --- a/lib/Service/DirectoryService.php +++ b/lib/Service/DirectoryService.php @@ -224,7 +224,7 @@ public function listCatalog (array $catalog): array $listing['title'] = $catalog['title']; $listing['organisation'] = $catalog['organisation']; - $listing['metaData'] = $catalog['metaData']; + $listing['metadata'] = $catalog['metadata']; if($this->config->hasKey($this->appName, 'mongoStorage') === false || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' diff --git a/src/modals/catalogiMetadata/AddCatalogiMetadata.vue b/src/modals/catalogiMetadata/AddCatalogiMetadata.vue index 4b093c66..575b2cbc 100644 --- a/src/modals/catalogiMetadata/AddCatalogiMetadata.vue +++ b/src/modals/catalogiMetadata/AddCatalogiMetadata.vue @@ -28,7 +28,7 @@ import { catalogiStore, navigationStore } from '../../store/store.js' required /> Welke meta data typen zou u uit deze catalogus willen overnemen? - - Metedata type 1 + + {{ metadataSingular.title }} @@ -80,14 +80,112 @@ export default { CogOutline, FileTreeOutline, }, + props: { + listingItem: { + type: Object, + required: true, + }, + }, data() { return { + metadata: [], + listing: '', } }, + watch: { + publicationItem: { + handler(newVal) { + console.log('test watch') + console.log(newVal) + if (newVal && newVal.id) { + this.fetchMetaData() + } + }, + immediate: true, // Ensures the watcher runs when the component is created + }, + }, + mounted() { + this.fetchMetaData() + }, methods: { openLink(url, type = '') { window.open(url, type) }, + CopyMetadata() { + this.loading = true + // metadataStore.metaDataItem.title = 'KOPIE: ' + metadataStore.metaDataItem.title + if (Object.keys(metadataStore.metaDataItem.properties).length === 0) { + delete metadataStore.metaDataItem.properties + } + delete metadataStore.metaDataItem.id + delete metadataStore.metaDataItem._id + fetch( + '/index.php/apps/opencatalogi/api/metadata', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(metadataStore.metaDataItem), + }, + ) + .then((response) => { + this.loading = false + this.succes = true + // Lets refresh the catalogiList + metadataStore.refreshMetaDataList() + response.json().then((data) => { + metadataStore.setMetaDataItem(data) + }) + navigationStore.setSelected('metaData') + // Wait for the user to read the feedback then close the model + const self = this + setTimeout(function() { + self.succes = false + navigationStore.setDialog(false) + }, 2000) + }) + .catch((err) => { + this.error = err + this.loading = false + }) + }, + fetchMetaData() { + this.loading = true + console.log('test1') + console.log(directoryStore.listingItem) + if (directoryStore.listingItem && Array.isArray(directoryStore.listingItem.metadata)) { + directoryStore.listingItem?.metadata.forEach(metadataSingular => { + console.log('test2') + fetch( + '/index.php/apps/opencatalogi/api/metadata?source=' + metadataSingular, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }, + ) + .then((response) => { + this.loading = false + this.succes = true + + response.json().then( + (data) => { + if (data?.results[0] !== undefined) { + this.metaData.push(data.results[0]) + } + return data + }, + ) + }) + .catch((err) => { + this.error = err + this.loading = false + }) + }) + } + }, }, } diff --git a/src/store/modules/directory.js b/src/store/modules/directory.js index bad527f5..3405b2b1 100644 --- a/src/store/modules/directory.js +++ b/src/store/modules/directory.js @@ -10,7 +10,7 @@ export const useDirectoryStore = defineStore( }), actions: { setListingItem(listingItem) { - this.listingItem = listingItem && new Listing(listingItem) + this.listingItem = listingItem ? new Listing(listingItem) : false console.log('Active directory item set to ' + listingItem && listingItem.id) }, setListingList(listingList) { diff --git a/src/views/publications/PublicationDetail.vue b/src/views/publications/PublicationDetail.vue index 9d96e7d6..3cb73993 100644 --- a/src/views/publications/PublicationDetail.vue +++ b/src/views/publications/PublicationDetail.vue @@ -131,6 +131,10 @@ import { catalogiStore, metadataStore, navigationStore, publicationStore } from Gewijzigd: {{ publicationStore.publicationItem.modified }} +
+ Bron: + {{ publicationStore.publicationItem.source }} +
Catalogi: Loading... From c2479fc4bcfd1277635d1a9a8c315a1f51532069 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Fri, 16 Aug 2024 13:15:15 +0200 Subject: [PATCH 06/52] Fixes on missing fields and updating listings --- appinfo/routes.php | 2 +- lib/Controller/DirectoryController.php | 31 +++++++ lib/Db/Listing.php | 1 - lib/Db/MetaData.php | 7 +- lib/Migration/Version6Date20240816084024.php | 70 +++++++++++++++ lib/Service/DirectoryService.php | 94 ++++++++++++-------- 6 files changed, 163 insertions(+), 42 deletions(-) create mode 100644 lib/Migration/Version6Date20240816084024.php diff --git a/appinfo/routes.php b/appinfo/routes.php index e58f75ba..7de3a4a1 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -21,7 +21,7 @@ ['name' => 'search#index', 'url' => '/api/search', 'verb' => 'GET'], ['name' => 'search#show', 'url' => '/api/search/{id}', 'verb' => 'GET'], ['name' => 'directory#page', 'url' => '/directory', 'verb' => 'GET'], - ['name' => 'directory#add', 'url' => '/api/directory/add', 'verb' => 'POST'], + ['name' => 'directory#synchronise', 'url' => '/api/directory/{id}/sync', 'verb' => 'GET'], ['name' => 'configuration#index', 'url' => '/configuration', 'verb' => 'GET'], ['name' => 'configuration#create', 'url' => '/configuration', 'verb' => 'POST'], ['name' => 'search#preflighted_cors', 'url' => '/api/{path}', 'verb' => 'OPTIONS', 'requirements' => ['path' => '.+']] diff --git a/lib/Controller/DirectoryController.php b/lib/Controller/DirectoryController.php index 53f32965..7dd649ca 100644 --- a/lib/Controller/DirectoryController.php +++ b/lib/Controller/DirectoryController.php @@ -213,4 +213,35 @@ public function destroy(string|int $id, ObjectService $objectService): JSONRespo // get post from requests return new JSONResponse($returnData); } + + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function synchronise(string|int $id, DirectoryService $directoryService, ObjectService $objectService): JSONResponse + { + if($this->config->hasKey($this->appName, 'mongoStorage') === false + || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' + ) { + try { + $object = $this->listingMapper->find(id: (int) $id)->jsonSerialize(); + } catch (DoesNotExistException $exception) { + return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404); + } + } else { + $dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation'); + $dbConfig['headers']['api-key'] = $this->config->getValueString(app: $this->appName, key: 'mongodbKey'); + $dbConfig['mongodbCluster'] = $this->config->getValueString(app: $this->appName, key: 'mongodbCluster'); + + $filters['_id'] = (string) $id; + + $object = $objectService->findObject(filters: $filters, config: $dbConfig); + + $url = $object['directory']; + } + + $directoryService->fetchFromExternalDirectory(url: $url, update: true); + + return new JsonResponse(data: $object, statusCode: 200); + } } diff --git a/lib/Db/Listing.php b/lib/Db/Listing.php index b11d24dd..2470afa8 100644 --- a/lib/Db/Listing.php +++ b/lib/Db/Listing.php @@ -10,7 +10,6 @@ class Listing extends Entity implements JsonSerializable { protected ?string $title = null; - protected ?string $reference = null; protected ?string $summary = null; protected ?string $description = null; protected ?string $search = null; diff --git a/lib/Db/MetaData.php b/lib/Db/MetaData.php index ced83048..46328aec 100644 --- a/lib/Db/MetaData.php +++ b/lib/Db/MetaData.php @@ -12,13 +12,15 @@ class MetaData extends Entity implements JsonSerializable protected ?string $title = null; protected ?string $version = null; protected ?string $description = null; - protected ?array $required = []; - protected ?array $properties = []; + protected ?string $summary = null; + protected ?array $required = []; + protected ?array $properties = []; public function __construct() { $this->addType(fieldName: 'title', type: 'string'); $this->addType(fieldName: 'version', type: 'string'); $this->addType(fieldName: 'description', type: 'string'); + $this->addType(fieldName: 'summary', type: 'string'); $this->addType(fieldName: 'required', type: 'json'); $this->addType(fieldName: 'properties', type: 'json'); @@ -60,6 +62,7 @@ public function jsonSerialize(): array 'title' => $this->title, 'version' => $this->version, 'description' => $this->description, + 'summary' => $this->summary, 'required' => $this->required, 'properties' => $this->properties, ]; diff --git a/lib/Migration/Version6Date20240816084024.php b/lib/Migration/Version6Date20240816084024.php new file mode 100644 index 00000000..028dfbb2 --- /dev/null +++ b/lib/Migration/Version6Date20240816084024.php @@ -0,0 +1,70 @@ +hasTable(tableName: 'listings') === true) { + $table = $schema->getTable(tableName: 'listings'); + + if($table->hasColumn(name: 'reference') === true) { + $table->dropColumn(name: 'reference'); + } + } + + if($schema->hasTable(tableName: 'metadata') === true) { + $table = $schema->getTable(tableName: 'metadata'); + + if($table->hasColumn(name: 'summary') === true) { + $column = $table->addColumn(name: 'summary', typeName: Types::STRING); + $column->setNotnull(notnull: false)->setDefault(default: null); + } + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} diff --git a/lib/Service/DirectoryService.php b/lib/Service/DirectoryService.php index 4de3e99b..87e9e3b4 100644 --- a/lib/Service/DirectoryService.php +++ b/lib/Service/DirectoryService.php @@ -34,8 +34,8 @@ private function getDirectoryEntry(string $catalogId): array 'title' => '', 'summary' => '', 'description' => '', - 'search' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute(routeName:"opencatalogi.search.index")), - 'directory' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index")), + 'search' => $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.search.index")), + 'directory' => $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index")), 'metadata' => '', 'status' => '', 'lastSync' => $now->format(format: 'c'), @@ -52,7 +52,7 @@ public function registerToExternalDirectory (array $newDirectory = [], ?string $ } - if($this->config->getValueString($this->appName, 'mongoStorage') !== '1') { + if($this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1') { $catalogi = $this->listingMapper->findAll(); } else { $dbConfig['base_uri'] = $this->config->getValueString('opencatalogi', 'mongodbLocation'); @@ -68,7 +68,7 @@ public function registerToExternalDirectory (array $newDirectory = [], ?string $ } unset($catalog['_id'], $catalog['id'], $catalog['_schema']); - if($catalog['directory'] !== $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index"))) { + if($catalog['directory'] !== $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index"))) { continue; } @@ -84,18 +84,23 @@ public function registerToExternalDirectory (array $newDirectory = [], ?string $ } - private function createDirectoryFromResult(array $result): ?array + private function createDirectoryFromResult(array $result, bool $update = false): ?array { unset($result['id']); - $myDirectory = $this->getDirectoryEntry(''); + $myDirectory = $this->getDirectoryEntry(catalogId: ''); if( isset($result['directory']) === false || $result['directory'] === $myDirectory['directory'] - || count($this->listDirectory(filters: ['catalogId' => $result['catalogId'], 'directory' => $result['directory']])) > 0 + || ( + count($this->listDirectory(filters: ['catalogId' => $result['catalogId'], 'directory' => $result['directory']])) > 0 + && $update === false + ) ) { return null; + } else if (count($this->listDirectory(filters: ['catalogId' => $result['catalogId'], 'directory' => $result['directory']])) > 0 && $update === true) { + $id = $this->listDirectory(filters: ['catalogId' => $result['catalogId'], 'directory' => $result['directory']])[0]['id']; } if($this->config->getValueString($this->appName, 'mongoStorage') === '1') { @@ -105,30 +110,43 @@ private function createDirectoryFromResult(array $result): ?array $result['_schema'] = 'directory'; - $returnData = $this->objectService->saveObject( + if(isset($id) === true) { + $this->objectService->updateObject( + filters: ['id' => $id], + update: $result, + config: $dbConfig + ); + } + + return $this->objectService->saveObject( data: $result, config: $dbConfig ); } else { - $this->listingMapper->createFromArray($result); + if(isset($id) === true) { + return $this->listingMapper->updateFromArray(id: $id, object: $result)->jsonSerialize(); + } + return $this->listingMapper->createFromArray(object: $result)->jsonSerialize(); } - - return $returnData; } - public function fetchFromExternalDirectory(array $directory = [], ?string $url = null): array + public function fetchFromExternalDirectory(array $directory = [], ?string $url = null, bool $update = false): array { if($directory !== [] && $url === null) { $url = $directory['directory']; } - $result = $this->client->get($url); + $result = $this->client->get(uri: $url); + + if($result->getHeader('content-type') !== 'application/json') { + $result = $this->client->get(uri: rtrim(string: $url, characters: '/').'/apps/opencatalogi/api/directory'); + } - $results = json_decode($result->getBody()->getContents(), true); + $results = json_decode(json: $result->getBody()->getContents(), associative: true); $addedDirectories = []; foreach($results['results'] as $record) { - $addedDirectories[] = $this->createDirectoryFromResult($record); + $addedDirectories[] = $this->createDirectoryFromResult(result: $record, update: $update); } return $addedDirectories; @@ -141,8 +159,8 @@ public function updateToExternalDirectory(): array public function listDirectory(array $filters = [], int $limit = 30, int $offset = 0): array { - if ($this->config->hasKey($this->appName, 'mongoStorage') === false - || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' + if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false + || $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1' ) { $filters['catalog_id'] = $filters['catalogId']; unset($filters['catalogId']); @@ -160,21 +178,21 @@ public function listDirectory(array $filters = [], int $limit = 30, int $offset public function deleteListing(string $catalogId, string $directoryUrl): void { - if($this->config->hasKey($this->appName, 'mongoStorage') === false - || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' + if($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false + || $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1' ) { $results = $this->listingMapper->findAll(filters: ['directory' => $directoryUrl, 'catalog_id' => $catalogId]); foreach($results as $result) { - $this->listingMapper->delete($result); + $this->listingMapper->delete(entity: $result); } return; } $dbConfig = [ - 'base_uri' => $this->config->getValueString($this->appName, 'mongodbLocation'), - 'headers' => ['api-key' => $this->config->getValueString($this->appName, 'mongodbKey')], - 'mongodbCluster' => $this->config->getValueString($this->appName, 'mongodbCluster') + 'base_uri' => $this->config->getValueString(app: $this->appName, key: 'mongodbLocation'), + 'headers' => ['api-key' => $this->config->getValueString(app: $this->appName, key: 'mongodbKey')], + 'mongodbCluster' => $this->config->getValueString(app: $this->appName, key: 'mongodbCluster') ]; $results = $this->objectService->findObjects(filters: ['directory' => $directoryUrl, 'catalogId' => $catalogId, '_schema' => 'directory'], config: $dbConfig); @@ -188,24 +206,24 @@ public function deleteListing(string $catalogId, string $directoryUrl): void public function directoryExists(string $catalogId): bool { - $directoryUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index")); + $directoryUrl = $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index")); - if($this->config->hasKey($this->appName, 'mongoStorage') === false - || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' + if($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false + || $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1' ) { $results = $this->listingMapper->findAll(filters: ['directory' => $directoryUrl, 'catalog_id' => $catalogId]); return count($results) > 0; } $dbConfig = [ - 'base_uri' => $this->config->getValueString($this->appName, 'mongodbLocation'), - 'headers' => ['api-key' => $this->config->getValueString($this->appName, 'mongodbKey')], - 'mongodbCluster' => $this->config->getValueString($this->appName, 'mongodbCluster') + 'base_uri' => $this->config->getValueString(app: $this->appName, key: 'mongodbLocation'), + 'headers' => ['api-key' => $this->config->getValueString(app: $this->appName, key: 'mongodbKey')], + 'mongodbCluster' => $this->config->getValueString(app: $this->appName, key: 'mongodbCluster') ]; $results = $this->objectService->findObjects(filters: ['directory' => $directoryUrl, 'catalogId' => $catalogId, '_schema' => 'directory'], config: $dbConfig); - return count($results['documents']) > 0; + return count(value: $results['documents']) > 0; } @@ -213,9 +231,9 @@ public function listCatalog (array $catalog): array { $catalogId = $catalog['id']; if($catalog['listed'] === false) { - $this->deleteListing(catalogId: $catalogId, directoryUrl: $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index")),); + $this->deleteListing(catalogId: $catalogId, directoryUrl: $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index")),); return $catalog; - } else if ($this->directoryExists($catalogId) === true) { + } else if ($this->directoryExists(catalogId: $catalogId) === true) { return $catalog; } @@ -226,8 +244,8 @@ public function listCatalog (array $catalog): array $listing['organisation'] = $catalog['organisation']; $listing['metaData'] = $catalog['metaData']; - if($this->config->hasKey($this->appName, 'mongoStorage') === false - || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' + if($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false + || $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1' ) { $listing = $this->listingMapper->createFromArray(object: $listing); @@ -236,14 +254,14 @@ public function listCatalog (array $catalog): array try { $dbConfig = [ - 'base_uri' => $this->config->getValueString($this->appName, 'mongodbLocation'), - 'headers' => ['api-key' => $this->config->getValueString($this->appName, 'mongodbKey')], - 'mongodbCluster' => $this->config->getValueString($this->appName, 'mongodbCluster') + 'base_uri' => $this->config->getValueString(app: $this->appName, key: 'mongodbLocation'), + 'headers' => ['api-key' => $this->config->getValueString(app: $this->appName, key: 'mongodbKey')], + 'mongodbCluster' => $this->config->getValueString(app: $this->appName, key: 'mongodbCluster') ]; $listing['_schema'] = 'directory'; - $returnData = $this->objectService->saveObject($listing, $dbConfig); + $returnData = $this->objectService->saveObject(data: $listing, config: $dbConfig); return $catalog; } catch (\Exception $e) { $catalog['listed'] = false; From af6cc05baaed0caa976a82e8643439808fb35bd5 Mon Sep 17 00:00:00 2001 From: Remko Date: Fri, 16 Aug 2024 13:16:34 +0200 Subject: [PATCH 07/52] Added download button --- lib/Service/FileService.php | 2 +- src/dialogs/Dialogs.vue | 3 + .../publication/DownloadPublicationDialog.vue | 149 ++++++++++++++++++ src/views/publications/PublicationDetail.vue | 116 ++++++++------ 4 files changed, 217 insertions(+), 53 deletions(-) create mode 100644 src/dialogs/publication/DownloadPublicationDialog.vue diff --git a/lib/Service/FileService.php b/lib/Service/FileService.php index 9b33b0d6..de4ccad9 100644 --- a/lib/Service/FileService.php +++ b/lib/Service/FileService.php @@ -367,7 +367,7 @@ public function createFolder(string $folderPath): bool public function createPdf(string $twigTemplate, array $context): Mpdf { // Initialize Twig - $loader = new FilesystemLoader(paths: 'lib/Templates', rootPath: '/var/www/html/apps-extra/opencatalogi'); + $loader = new FilesystemLoader(paths: 'lib/Templates', rootPath: __DIR__ . '/../../'); $twig = new Environment($loader); // Render the Twig template diff --git a/src/dialogs/Dialogs.vue b/src/dialogs/Dialogs.vue index 87a8e1cd..d5a2a6fd 100644 --- a/src/dialogs/Dialogs.vue +++ b/src/dialogs/Dialogs.vue @@ -11,6 +11,7 @@ + @@ -51,6 +52,7 @@ import PublishPublicationDialog from './publication/PublishPublicationDialog.vue import DeletePublicationDataDialog from './publicationData/DeletePublicationDataDialog.vue' import CopyThemeDialog from './theme/CopyThemeDialog.vue' import DeleteThemeDialog from './theme/DeleteThemeDialog.vue' +import DownloadPublicationDialog from './publication/DownloadPublicationDialog.vue' export default { name: 'Dialogs', @@ -77,6 +79,7 @@ export default { CopyOrganisationDialog, DeleteThemeDialog, CopyThemeDialog, + DownloadPublicationDialog, }, } diff --git a/src/dialogs/publication/DownloadPublicationDialog.vue b/src/dialogs/publication/DownloadPublicationDialog.vue new file mode 100644 index 00000000..b6b9b35d --- /dev/null +++ b/src/dialogs/publication/DownloadPublicationDialog.vue @@ -0,0 +1,149 @@ + + + + + + + diff --git a/src/views/publications/PublicationDetail.vue b/src/views/publications/PublicationDetail.vue index 73f64308..ee0899e6 100644 --- a/src/views/publications/PublicationDetail.vue +++ b/src/views/publications/PublicationDetail.vue @@ -11,22 +11,18 @@ import { ref } from 'vue' {{ publicationStore.publicationItem.title }} - - Kopiƫren - + Publiceren - + @@ -63,6 +61,12 @@ import { ref } from 'vue' Archiveren + + + Downloaden + diff --git a/src/modals/publicationData/EditPublicationDataModal.vue b/src/modals/publicationData/EditPublicationDataModal.vue index d58f23dc..46d93e72 100644 --- a/src/modals/publicationData/EditPublicationDataModal.vue +++ b/src/modals/publicationData/EditPublicationDataModal.vue @@ -55,6 +55,8 @@ import { NcLoadingIcon, NcNoteCard, } from '@nextcloud/vue' +import { getMetaDataId } from './../../services/getMetaDataId.js' + import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue' export default { @@ -184,7 +186,7 @@ export default { ...publicationStore.publicationItem, id: publicationStore.publicationItem.id, catalogi: publicationStore.publicationItem.catalogi.id, - metaData: publicationStore.publicationItem.metaData.id, + metaData: getMetaDataId(publicationStore.publicationItem.metaData), }), }, ) diff --git a/src/services/getMetaDataId.js b/src/services/getMetaDataId.js new file mode 100644 index 00000000..20daf659 --- /dev/null +++ b/src/services/getMetaDataId.js @@ -0,0 +1,4 @@ +export const getMetaDataId = (url) => { + const metaDataId = url.substring(url.lastIndexOf('/') + 1, url.length) + return metaDataId +} diff --git a/src/store/modules/publication.js b/src/store/modules/publication.js index 97fb291d..bd293027 100644 --- a/src/store/modules/publication.js +++ b/src/store/modules/publication.js @@ -6,6 +6,7 @@ export const usePublicationStore = defineStore( 'publication', { state: () => ({ publicationItem: false, + publicationMetaData: false, publicationList: [], publicationDataKey: false, attachmentItem: false, @@ -162,6 +163,9 @@ export const usePublicationStore = defineStore( this.attachmentFile = files console.log('Active attachment files set to ' + files) }, + setPublicationMetaData(metaData) { + this.publicationMetaData = metaData + }, }, setPublicationList(publicationList) { this.publicationList = publicationList.map((publicationItem) => new Publication(publicationItem)) @@ -262,5 +266,8 @@ export const usePublicationStore = defineStore( setAttachmentFile(files) { this.attachmentFile = files }, + setPublicationMetaData(metaData) { + this.publicationMetaData = metaData + }, }, ) diff --git a/src/views/directory/ListingDetails.vue b/src/views/directory/ListingDetails.vue deleted file mode 100644 index 137da947..00000000 --- a/src/views/directory/ListingDetails.vue +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - diff --git a/src/views/publications/PublicationDetail.vue b/src/views/publications/PublicationDetail.vue index 0f731456..d9741dbc 100644 --- a/src/views/publications/PublicationDetail.vue +++ b/src/views/publications/PublicationDetail.vue @@ -209,7 +209,7 @@ import { ref } from 'vue' :bold="false" :active="publicationStore.attachmentId === attachment.id" :force-display-actions="true" - :details="(attachment?.published && attachment?.published <= getTime) ? 'Gepubliseerd' : 'Niet gepubliseerd'"> + :details="(attachment?.published && attachment?.published <= getTime) ? 'Gepubliceerd' : 'Niet gepubliceerd'"> Welke meta data typen zou u uit deze catalogus willen overnemen? - - {{ metadataSingular }} - +
+ + {{ metadataSingular }} + +
+ @@ -127,70 +130,52 @@ export default { NcCheckboxRadioSwitch, NcLoadingIcon, }, - mounted() { - metadataStore.refreshMetaDataList() - }, data() { return { checkedMetadata: {}, listing: '', - loading: false + loading: false, syncLoading: false, } }, - // created() { - // if (directoryStore?.listingItem?.metadata !== undefined) { - // this.checkMetadataSwitches() - // } - // }, - watch: { - checkedMetadata: { - handler(newValue, oldValue) { - const metadataUrl = Object.entries(newValue)[0][0] - const shouldCopyMetadata = Object.entries(newValue)[0][1] - this.loading = true - if (shouldCopyMetadata === true) { - this.copyMetadata(metadataUrl) - } else if (shouldCopyMetadata === false) { - console.log('deletemetadata') - this.deleteMetadata(metadataUrl) - } - this.checkMetadataSwitches(); - this.loading = false - }, - deep: true - }, - 'metadataStore.metaDataList': { - handler(newValue, oldValue) { - if (directoryStore?.listingItem !== false && metaDataStore?.metaDataList) { - this.loading = true - this.checkMetadataSwitches(); - } - }, - deep: true, // If listingItem has nested objects and you want to track changes in them as well - immediate: true // Optionally, run the handler immediately on initialization - }, - 'directoryStore.listingItem': { - handler(newValue, oldValue) { - if (directoryStore?.listingItem !== false && metaDataStore?.metaDataList) { - this.loading = true - this.checkMetadataSwitches(); - } - }, - deep: true, // If listingItem has nested objects and you want to track changes in them as well - immediate: true // Optionally, run the handler immediately on initialization - }, - }, + watch: { + checkedMetadata: { + handler(newValue, oldValue) { + const metadataUrl = Object.entries(newValue)[0][0] + const shouldCopyMetadata = Object.entries(newValue)[0][1] + this.loading = true + if (shouldCopyMetadata === true) { + this.copyMetadata(metadataUrl) + } else if (shouldCopyMetadata === false) { + this.deleteMetadata(metadataUrl) + } + this.loading = false + }, + deep: true, + }, + 'directoryStore.listingItem': { + handler(newValue, oldValue) { + if (directoryStore?.listingItem !== false && metadataStore?.metaDataList) { + this.loading = true + this.checkMetadataSwitches() + } + }, + deep: true, // If listingItem has nested objects and you want to track changes in them as well + immediate: true, // Optionally, run the handler immediately on initialization + }, + }, + mounted() { + metadataStore.refreshMetaDataList() + }, methods: { openLink(url, type = '') { window.open(url, type) }, - deleteMetadata(metadataUrl) { - console.log('deleteMetadata') - let metadataId; - metadataId = this.getMetadataId(metadataUrl) + deleteMetadata(metadataUrl) { + let metadataId + metadataId = this.getMetadataId(metadataUrl) - fetch( + fetch( `/index.php/apps/opencatalogi/api/metadata/${metadataId}`, { method: 'DELETE', @@ -206,44 +191,32 @@ export default { this.error = err this.loading = false }) - }, - getMetadataId(metadataUrl) { - console.log('getMetadataId') - - console.log(metadataStore.metadataList) - metadataStore.metadataList.forEach((metadataItem) => { - console.log('metadataItem', metadataItem.source, 'metadataUrl', metadataUrl) - const isEqual = (metadataUrl === metadataItem.source); - if (isEqual) { - return metadataItem.id - } - }) - }, - checkMetadataSwitches() { - console.log('createMetadata') - console.log('refresh'); - metadataStore.refreshMetaDataList() - console.log('refresh done'); + }, + getMetadataId(metadataUrl) { + metadataStore.metadataList.forEach((metadataItem) => { + const isEqual = (metadataUrl === metadataItem.source) + if (isEqual) { + return metadataItem.id + } + }) + }, + checkMetadataSwitches() { + metadataStore.refreshMetaDataList() - console.log('check the switches'); - if (directoryStore?.listingItem?.metadata !== undefined) { - directoryStore.listingItem.metadata.forEach((metadataItem) => { - const exists = metadataStore.metaDataList.some(metaData => metaData.source === metadataItem.source); - this.$set(this.checkedMetadata, metadataItem.source, exists); - }); - } - console.log('check the switches done'); - - this.loading = false - console.log('set loading false'); + if (directoryStore?.listingItem?.metadata !== undefined) { + directoryStore.listingItem.metadata.forEach((metadataItem) => { + const exists = metadataStore.metaDataList.some(metaData => metaData.source === metadataItem.source) + this.$set(this.checkedMetadata, metadataItem.source, exists) + }) + } - }, + this.loading = false + }, copyMetadata(metadataUrl) { - console.log('copyMetadata') fetch( metadataUrl, { - method: 'GET' + method: 'GET', }, ) .then((response) => { @@ -260,7 +233,6 @@ export default { }) }, createMetadata(data) { - console.log('createMetadata') data.title = 'KOPIE: ' + data.title if (Object.keys(data.properties).length === 0) { From b2707af3eee784b5118c652768d9e05ab310dbfd Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Mon, 19 Aug 2024 13:05:21 +0200 Subject: [PATCH 29/52] WIP fixes add eigenschap from copied metadata --- .../AddPublicationDataModal.vue | 17 ++++++ src/views/publications/PublicationDetail.vue | 52 +++++++++++++------ 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/modals/publicationData/AddPublicationDataModal.vue b/src/modals/publicationData/AddPublicationDataModal.vue index 9a82c2ad..f2db2c6f 100644 --- a/src/modals/publicationData/AddPublicationDataModal.vue +++ b/src/modals/publicationData/AddPublicationDataModal.vue @@ -88,6 +88,23 @@ export default { }, computed: { mapMetadataEigenschappen() { + if (publicationStore.publicationMetaData) { + const incomingUrl = new URL(publicationStore.publicationMetaData.source) + if (incomingUrl?.host !== window.location.host) { + return { + inputLabel: 'Publicatie type eigenschap', + options: Object.keys(publicationStore.publicationMetaData?.properties) + .filter((prop) => !Object.keys(publicationStore.publicationItem?.data).includes(prop)) + .map((prop) => ({ + id: prop, + label: prop, + })), + } + } + } + + console.log('test') + return { inputLabel: 'Publicatie type eigenschap', options: Object.values(publicationStore.publicationMetaData?.properties) diff --git a/src/views/publications/PublicationDetail.vue b/src/views/publications/PublicationDetail.vue index a2f72263..13c9ec6f 100644 --- a/src/views/publications/PublicationDetail.vue +++ b/src/views/publications/PublicationDetail.vue @@ -488,7 +488,7 @@ export default { if (!this.upToDate || JSON.stringify(newPublicationItem) !== JSON.stringify(oldPublicationItem)) { this.publication = publicationStore.publicationItem this.fetchCatalogi(publicationStore.publicationItem.catalogi.id) - this.fetchMetaData(getMetaDataId(publicationStore.publicationItem.metaData)) + // this.fetchMetaData(publicationStore.publicationItem.metaData) publicationStore.publicationItem && this.fetchData(publicationStore.publicationItem.id) } }, @@ -500,7 +500,7 @@ export default { this.publication = publicationStore.publicationItem this.fetchCatalogi(this.publication.catalogi?.id, true) - this.fetchMetaData(getMetaDataId(publicationStore.publicationItem.metaData), true) + // this.fetchMetaData(publicationStore.publicationItem.metaData, true) publicationStore.publicationItem && this.fetchData(publicationStore.publicationItem.id) }, @@ -515,7 +515,7 @@ export default { this.publication = data // this.oldZaakId = id this.fetchCatalogi(data.catalogi.id) - this.fetchMetaData(getMetaDataId(data.metaData)) + this.fetchMetaData(data.metaData) publicationStore.getPublicationAttachments(id) // this.loading = false }) @@ -547,20 +547,42 @@ export default { if (loading) { this.metaDataLoading = true } - fetch(`/index.php/apps/opencatalogi/api/metadata/${metadataId}`, { - method: 'GET', - }) - .then((response) => { - response.json().then((data) => { - this.metadata = data - publicationStore.setPublicationMetaData(data) - }) - if (loading) { this.metaDataLoading = false } + console.log('metadataID', metadataId) + const incomingUrl = new URL(metadataId) + if (incomingUrl.host === window.location.host) { + const id = getMetaDataId(metadataId) + fetch(`/index.php/apps/opencatalogi/api/metadata/${id}`, { + method: 'GET', }) - .catch((err) => { - console.error(err) - if (loading) { this.metaDataLoading = false } + .then((response) => { + response.json().then((data) => { + this.metadata = data + publicationStore.setPublicationMetaData(data) + }) + if (loading) { this.metaDataLoading = false } + }) + .catch((err) => { + console.error(err) + if (loading) { this.metaDataLoading = false } + }) + } + if (incomingUrl.host !== window.location.host) { + fetch(incomingUrl, { + method: 'GET', }) + .then((response) => { + response.json().then((data) => { + this.metadata = data + publicationStore.setPublicationMetaData(data) + }) + if (loading) { this.metaDataLoading = false } + }) + .catch((err) => { + console.error(err) + if (loading) { this.metaDataLoading = false } + }) + } + }, getTime() { const timeNow = new Date().toISOString() From 6e053336d3dc5a5a9c449f6a3d56e7c3c3b177dd Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 19 Aug 2024 13:47:04 +0200 Subject: [PATCH 30/52] Fix statuscode field nullability --- lib/Migration/Version6Date20240816111746.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Migration/Version6Date20240816111746.php b/lib/Migration/Version6Date20240816111746.php index c1a5632e..5acf0d18 100644 --- a/lib/Migration/Version6Date20240816111746.php +++ b/lib/Migration/Version6Date20240816111746.php @@ -44,7 +44,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt $table = $schema->getTable(tableName: 'listings'); if($table->hasColumn(name: 'status_code') === false) { - $table->addColumn(name: 'status_code', typeName: Types::INTEGER); + $table->addColumn(name: 'status_code', typeName: Types::INTEGER)->setNotnull(notnull: false); } } From 5c908fccc398f28e98af7b2ef9f9ef7d9d934cc5 Mon Sep 17 00:00:00 2001 From: Thijn Date: Mon, 19 Aug 2024 14:39:40 +0200 Subject: [PATCH 31/52] finished filtered metadata --- .../DeleteCatalogiMetadata.vue | 3 +- .../catalogiMetadata/AddCatalogiMetadata.vue | 9 +- .../publication/AddPublicationModal.vue | 42 +- src/store/modules/publication.js | 425 +++++++++--------- src/views/catalogi/CatalogiDetails.vue | 16 +- src/views/publications/PublicationDetail.vue | 7 +- 6 files changed, 265 insertions(+), 237 deletions(-) diff --git a/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue b/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue index a4b86a17..e7d3100d 100644 --- a/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue +++ b/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue @@ -1,4 +1,5 @@ @@ -67,7 +68,7 @@ export default { methods: { DeleteCatalogiMetadata() { const metadataArray = catalogiStore.catalogiItem?.metadata - .filter((metaId) => metaId.toString() !== metadataStore.metaDataItem?.id.toString()) + .filter((metaId) => getMetaDataId(metaId) !== metadataStore.metaDataItem?.id.toString()) this.loading = true fetch( diff --git a/src/modals/catalogiMetadata/AddCatalogiMetadata.vue b/src/modals/catalogiMetadata/AddCatalogiMetadata.vue index 575b2cbc..07998d84 100644 --- a/src/modals/catalogiMetadata/AddCatalogiMetadata.vue +++ b/src/modals/catalogiMetadata/AddCatalogiMetadata.vue @@ -1,4 +1,5 @@ @@ -70,6 +71,7 @@ export default { success: null, error: false, errorCode: '', + hasUpdated: false, } }, mounted() { @@ -125,8 +127,8 @@ export default { }) .then((response) => { response.json().then((data) => { - const metadataListAsString = metadataList.map(String) - const filteredData = data.results.filter((meta) => !metadataListAsString.includes(meta?.id.toString())) + const metadataIds = metadataList.map(getMetaDataId) + const filteredData = data.results.filter((meta) => !metadataIds.includes(meta?.id.toString())) this.metaData = { options: filteredData.map((metaData) => ({ @@ -181,10 +183,13 @@ export default { self.success = null self.closeModal() }, 2000) + + this.hasUpdated = false }) .catch((err) => { this.error = err this.loading = false + this.hasUpdated = false }) }, }, diff --git a/src/modals/publication/AddPublicationModal.vue b/src/modals/publication/AddPublicationModal.vue index 5860b443..c6c9ab1c 100644 --- a/src/modals/publication/AddPublicationModal.vue +++ b/src/modals/publication/AddPublicationModal.vue @@ -89,7 +89,7 @@ import { navigationStore, publicationStore } from '../../store/store.js'

Publicaties worden gedefineerd door publicatie typen, van welk publicatie type wit u een publicatie aanmaken?

- catalogus.id.toString() === this.catalogi.value.id.toString())[0] + // step 2: get all the metadata ID's from the `metadata` property inside the catalogus + const metadataIds = selectedCatalogus.metadata.map((metadataUrl) => getMetaDataId(metadataUrl)) + // step 3: get the full metadata's from the metadataIds + const filteredMetadata = this.metaDataList + .filter((metadata) => metadataIds.includes(metadata.id.toString())) + + return { + options: filteredMetadata.map((metaData) => ({ + id: metaData.id, + source: metaData.source, + label: metaData.title, + })), + } + }, + }, watch: { data: { handler(data) { @@ -238,6 +266,8 @@ export default { }) .then((response) => { response.json().then((data) => { + this.catalogiList = data.results + const selectedCatalogus = navigationStore.getTransferData() !== 'ignore selectedCatalogus' ? data.results.filter((catalogus) => catalogus.id.toString() === navigationStore.selectedCatalogus.toString())[0] : null @@ -270,15 +300,7 @@ export default { }) .then((response) => { response.json().then((data) => { - - this.metaData = { - options: Object.entries(data.results).map((metaData) => ({ - id: metaData[1].id ?? metaData[1]._id, - source: metaData[1].source ?? metaData[1].source, - label: metaData[1].title ?? metaData[1].name, - })), - - } + this.metaDataList = data.results }) this.metaDataLoading = false }) diff --git a/src/store/modules/publication.js b/src/store/modules/publication.js index bd293027..b96aadd4 100644 --- a/src/store/modules/publication.js +++ b/src/store/modules/publication.js @@ -2,221 +2,105 @@ import { Attachment, Publication } from '../../entities/index.js' import { defineStore } from 'pinia' -export const usePublicationStore = defineStore( - 'publication', { - state: () => ({ - publicationItem: false, - publicationMetaData: false, - publicationList: [], - publicationDataKey: false, - attachmentItem: false, - attachmentFile: null, - publicationAttachments: false, - conceptPublications: [], - conceptAttachments: [], - }), - actions: { - setPublicationItem(publicationItem) { - // To prevent forms etc from braking we alway use a default/skeleton object - this.publicationItem = publicationItem && new Publication(publicationItem) - console.log('Active publication item set to ' + publicationItem && publicationItem.id) - }, - setPublicationList(publicationList) { - this.publicationList = publicationList.map((publicationItem) => new Publication(publicationItem)) - console.log('Active publication item set to ' + publicationList.length) - }, - async refreshPublicationList(normalSearch = [], advancedSearch = null, sortField = null, sortDirection = null) { - // @todo this might belong in a service? - let endpoint = '/index.php/apps/opencatalogi/api/publications' - const params = new URLSearchParams() - for (const item of normalSearch) { - if (item.key && item.value !== undefined) { - params.append(item.key, item.value) - } - } - if (advancedSearch !== null && advancedSearch !== '') { - params.append('_search', advancedSearch) - } - if (sortField !== null && sortField !== '' && sortDirection !== null && sortDirection !== '') { - if (sortField === 'Titel') { - sortField = 'title' - } - if (sortField === 'Datum gepubliceerd') { - sortField = 'published' - } - if (sortField === 'Datum aangepast') { - sortField = 'modified' - } - params.append('_order[' + sortField + ']', sortDirection) - } - if (params.toString()) { - endpoint += '?' + params.toString() - } - - return fetch( - endpoint, - { - method: 'GET', - }, - ) - .then( - (response) => { - response.json().then( - (data) => { - this.setPublicationList(data?.results) - return data - }, - ) - }, - ) - .catch( - (err) => { - console.error(err) - return err - }, - ) - }, - getPublicationAttachments(publicationId) { - fetch( - `/index.php/apps/opencatalogi/api/publications/${publicationId}/attachments`, - { - method: 'GET', - }, - ) - .then( - (response) => { - response.json().then( - (data) => { - this.publicationAttachments = data.results.map( - (attachmentItem) => new Attachment(attachmentItem), - ) - return data - }, - ) - }, - ) - .catch( - (err) => { - console.error(err) - return err - }, - ) - }, - getConceptPublications() { // @todo this might belong in a service? - fetch( - '/index.php/apps/opencatalogi/api/publications?status=concept', - { - method: 'GET', - }, - ) - .then( - (response) => { - response.json().then( - (data) => { - this.conceptPublications = data - return data - }, - ) - }, - ) - .catch( - (err) => { - console.error(err) - return err - }, - ) - }, - getConceptAttachments() { // @todo this might belong in a service? - fetch( - '/index.php/apps/opencatalogi/api/attachments?status=concept', - { - method: 'GET', - }, - ) - .then( - (response) => { - response.json().then( - (data) => { - this.conceptAttachments = data - return data - }, - ) - }, - ) - .catch( - (err) => { - console.error(err) - return err - }, - ) - }, - // @todo why does the following run through the store? -- because its impossible with props, and its vital information for the modal. - setPublicationDataKey(publicationDataKey) { - this.publicationDataKey = publicationDataKey - console.log('Active publication data key set to ' + publicationDataKey) - }, - setAttachmentItem(attachmentItem) { - this.attachmentItem = attachmentItem && new Attachment(attachmentItem) - console.log('Active attachment item set to ' + attachmentItem) - }, - setAttachmentFile(files) { - this.attachmentFile = files - console.log('Active attachment files set to ' + files) - }, - setPublicationMetaData(metaData) { - this.publicationMetaData = metaData - }, +export const usePublicationStore = defineStore('publication', { + state: () => ({ + publicationItem: false, + publicationMetaData: false, + publicationList: [], + publicationDataKey: false, + attachmentItem: false, + attachmentFile: null, + publicationAttachments: false, + conceptPublications: [], + conceptAttachments: [], + }), + actions: { + setPublicationItem(publicationItem) { + // To prevent forms etc from braking we alway use a default/skeleton object + this.publicationItem = publicationItem && new Publication(publicationItem) + console.log('Active publication item set to ' + publicationItem && publicationItem.id) }, setPublicationList(publicationList) { this.publicationList = publicationList.map((publicationItem) => new Publication(publicationItem)) console.log('Active publication item set to ' + publicationList.length) }, - /* istanbul ignore next */ // ignore this for Jest until moved into a service - async refreshPublicationList(search = null) { + async refreshPublicationList(normalSearch = [], advancedSearch = null, sortField = null, sortDirection = null) { // @todo this might belong in a service? let endpoint = '/index.php/apps/opencatalogi/api/publications' - if (search !== null && search !== '') { - endpoint = endpoint + '?_search=' + search + const params = new URLSearchParams() + for (const item of normalSearch) { + if (item.key && item.value !== undefined) { + params.append(item.key, item.value) + } } + if (advancedSearch !== null && advancedSearch !== '') { + params.append('_search', advancedSearch) + } + if (sortField !== null && sortField !== '' && sortDirection !== null && sortDirection !== '') { + if (sortField === 'Titel') { + sortField = 'title' + } + if (sortField === 'Datum gepubliceerd') { + sortField = 'published' + } + if (sortField === 'Datum aangepast') { + sortField = 'modified' + } + params.append('_order[' + sortField + ']', sortDirection) + } + if (params.toString()) { + endpoint += '?' + params.toString() + } + return fetch( endpoint, { method: 'GET', }, ) - .then((response) => { - response.json().then((data) => { - this.setPublicationList(data?.results) - return data - }) - }) - .catch((err) => { - console.error(err) - return err - }) + .then( + (response) => { + response.json().then( + (data) => { + this.setPublicationList(data?.results) + return data + }, + ) + }, + ) + .catch( + (err) => { + console.error(err) + return err + }, + ) }, - /* istanbul ignore next */ // ignore this for Jest until moved into a service getPublicationAttachments(publicationId) { fetch( - '/index.php/apps/opencatalogi/api/publications/' + publicationId + '/attachments', + `/index.php/apps/opencatalogi/api/publications/${publicationId}/attachments`, { method: 'GET', }, ) - .then((response) => { - response.json().then((data) => { - this.publicationAttachments = data.results.map( - (attachmentItem) => new Attachment(attachmentItem), + .then( + (response) => { + response.json().then( + (data) => { + this.publicationAttachments = data.results.map( + (attachmentItem) => new Attachment(attachmentItem), + ) + return data + }, ) - return data - }) - }) - .catch((err) => { - console.error(err) - return err - }) + }, + ) + .catch( + (err) => { + console.error(err) + return err + }, + ) }, - /* istanbul ignore next */ // ignore this for Jest until moved into a service getConceptPublications() { // @todo this might belong in a service? fetch( '/index.php/apps/opencatalogi/api/publications?status=concept', @@ -224,18 +108,23 @@ export const usePublicationStore = defineStore( method: 'GET', }, ) - .then((response) => { - response.json().then((data) => { - this.conceptPublications = data - return data - }) - }) - .catch((err) => { - console.error(err) - return err - }) + .then( + (response) => { + response.json().then( + (data) => { + this.conceptPublications = data + return data + }, + ) + }, + ) + .catch( + (err) => { + console.error(err) + return err + }, + ) }, - /* istanbul ignore next */ // ignore this for Jest until moved into a service getConceptAttachments() { // @todo this might belong in a service? fetch( '/index.php/apps/opencatalogi/api/attachments?status=concept', @@ -243,16 +132,22 @@ export const usePublicationStore = defineStore( method: 'GET', }, ) - .then((response) => { - response.json().then((data) => { - this.conceptAttachments = data - return data - }) - }) - .catch((err) => { - console.error(err) - return err - }) + .then( + (response) => { + response.json().then( + (data) => { + this.conceptAttachments = data + return data + }, + ) + }, + ) + .catch( + (err) => { + console.error(err) + return err + }, + ) }, // @todo why does the following run through the store? -- because its impossible with props, and its vital information for the modal. setPublicationDataKey(publicationDataKey) { @@ -265,9 +160,113 @@ export const usePublicationStore = defineStore( }, setAttachmentFile(files) { this.attachmentFile = files + console.log('Active attachment files set to ' + files) }, setPublicationMetaData(metaData) { this.publicationMetaData = metaData }, }, + setPublicationList(publicationList) { + this.publicationList = publicationList.map((publicationItem) => new Publication(publicationItem)) + console.log('Active publication item set to ' + publicationList.length) + }, + /* istanbul ignore next */ // ignore this for Jest until moved into a service + async refreshPublicationList(search = null) { + // @todo this might belong in a service? + let endpoint = '/index.php/apps/opencatalogi/api/publications' + if (search !== null && search !== '') { + endpoint = endpoint + '?_search=' + search + } + return fetch( + endpoint, + { + method: 'GET', + }, + ) + .then((response) => { + response.json().then((data) => { + this.setPublicationList(data?.results) + return data + }) + }) + .catch((err) => { + console.error(err) + return err + }) + }, + /* istanbul ignore next */ // ignore this for Jest until moved into a service + getPublicationAttachments(publicationId) { + fetch( + '/index.php/apps/opencatalogi/api/publications/' + publicationId + '/attachments', + { + method: 'GET', + }, + ) + .then((response) => { + response.json().then((data) => { + this.publicationAttachments = data.results.map( + (attachmentItem) => new Attachment(attachmentItem), + ) + return data + }) + }) + .catch((err) => { + console.error(err) + return err + }) + }, + /* istanbul ignore next */ // ignore this for Jest until moved into a service + getConceptPublications() { // @todo this might belong in a service? + fetch( + '/index.php/apps/opencatalogi/api/publications?status=concept', + { + method: 'GET', + }, + ) + .then((response) => { + response.json().then((data) => { + this.conceptPublications = data + return data + }) + }) + .catch((err) => { + console.error(err) + return err + }) + }, + /* istanbul ignore next */ // ignore this for Jest until moved into a service + getConceptAttachments() { // @todo this might belong in a service? + fetch( + '/index.php/apps/opencatalogi/api/attachments?status=concept', + { + method: 'GET', + }, + ) + .then((response) => { + response.json().then((data) => { + this.conceptAttachments = data + return data + }) + }) + .catch((err) => { + console.error(err) + return err + }) + }, + // @todo why does the following run through the store? -- because its impossible with props, and its vital information for the modal. + setPublicationDataKey(publicationDataKey) { + this.publicationDataKey = publicationDataKey + console.log('Active publication data key set to ' + publicationDataKey) + }, + setAttachmentItem(attachmentItem) { + this.attachmentItem = attachmentItem && new Attachment(attachmentItem) + console.log('Active attachment item set to ' + attachmentItem) + }, + setAttachmentFile(files) { + this.attachmentFile = files + }, + setPublicationMetaData(metaData) { + this.publicationMetaData = metaData + }, +}, ) diff --git a/src/views/catalogi/CatalogiDetails.vue b/src/views/catalogi/CatalogiDetails.vue index 32f10726..3c27d909 100644 --- a/src/views/catalogi/CatalogiDetails.vue +++ b/src/views/catalogi/CatalogiDetails.vue @@ -63,9 +63,9 @@ import { catalogiStore, metadataStore, navigationStore } from '../../store/store
-