diff --git a/.vscode/settings.json b/.vscode/settings.json
index fe76d727..73c4e5f3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -23,4 +23,6 @@
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
+ "javascript.preferences.importModuleSpecifier": "relative",
+ "javascript.preferences.importModuleSpecifierEnding": "js",
}
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 490b7f5d..051a7621 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -22,10 +22,15 @@
['name' => 'search#indexInternal', 'url' => '/api/search/internal', 'verb' => 'GET'],
['name' => 'search#show', 'url' => '/api/search/{id}', 'verb' => 'GET'],
['name' => 'search#showInternal', 'url' => '/api/search/internal/{id}', 'verb' => 'GET'],
+ ['name' => 'search#preflighted_cors', 'url' => '/api/{path}', 'verb' => 'OPTIONS', 'requirements' => ['path' => '.+']],
+ ['name' => 'themes#index', 'url' => '/search/themes', 'verb' => 'GET'],
+ ['name' => 'themes#index', 'url' => '/api/search/themes', 'verb' => 'GET'],
+ ['name' => 'themes#indexInternal', 'url' => '/api/themes', 'verb' => 'GET'],
+ ['name' => 'themes#show', 'url' => '/api/search/themes/{id}', 'verb' => 'GET'],
+ ['name' => 'themes#showInternal', 'url' => '/api/themes/{id}', 'verb' => 'GET'],
['name' => 'directory#page', 'url' => '/directory', 'verb' => 'GET'],
['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' => '.+']]
+ ['name' => 'configuration#create', 'url' => '/configuration', 'verb' => 'POST']
],
];
diff --git a/lib/Controller/AttachmentsController.php b/lib/Controller/AttachmentsController.php
index c32773da..74327310 100644
--- a/lib/Controller/AttachmentsController.php
+++ b/lib/Controller/AttachmentsController.php
@@ -35,9 +35,9 @@ public function __construct
private function insertNestedObjects(array $object, ObjectService $objectService, array $config): array
{
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
try {
- if(
+ if (
is_string(value: $value)
&& $key !== 'id'
&& Uuid::isValid(uuid: $value) === true
@@ -109,8 +109,8 @@ public function index(ObjectService $objectService): JSONResponse
$filters = $this->request->getParams();
unset($filters['_route']);
- foreach($filters as $key => $value) {
- if(str_starts_with($key, '_')) {
+ foreach ($filters as $key => $value) {
+ if (str_starts_with($key, '_')) {
unset($filters[$key]);
}
}
@@ -306,8 +306,8 @@ public function create(ObjectService $objectService, ElasticSearchService $elast
// Remove fields we should never post.
unset($data['id']);
- foreach($data as $key => $value) {
- if(str_starts_with(haystack: $key, needle: '_')) {
+ foreach ($data as $key => $value) {
+ if (str_starts_with(haystack: $key, needle: '_')) {
unset($data[$key]);
}
}
@@ -343,8 +343,8 @@ public function update(string|int $id, ObjectService $objectService, ElasticSear
// Remove fields we should never post.
unset($data['id']);
- foreach($data as $key => $value) {
- if(str_starts_with(haystack: $key, needle: '_')) {
+ foreach ($data as $key => $value) {
+ if (str_starts_with(haystack: $key, needle: '_')) {
unset($data[$key]);
}
}
diff --git a/lib/Controller/CatalogiController.php b/lib/Controller/CatalogiController.php
index 1d2dd062..73753297 100644
--- a/lib/Controller/CatalogiController.php
+++ b/lib/Controller/CatalogiController.php
@@ -44,7 +44,7 @@ public function index(ObjectService $objectService, SearchService $searchService
unset($filters['_route']);
$fieldsToSearch = ['title', 'description', 'summary'];
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
@@ -80,7 +80,7 @@ public function index(ObjectService $objectService, SearchService $searchService
*/
public function show(string|int $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
try {
@@ -124,11 +124,11 @@ public function create(ObjectService $objectService, DirectoryService $directory
}
// @todo dit is alleen omdat er een onredenlijke verplichting aan de database is toegeveoegd
- if(array_key_exists('metadata',$data) === false){
+ if (array_key_exists('metadata',$data) === false){
$data['metadata'] = [];
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$result = $this->catalogMapper->createFromArray(object: $data);
@@ -177,7 +177,7 @@ public function update(string|int $id, ObjectService $objectService, DirectorySe
unset($data['id']);
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$result = $this->catalogMapper->updateFromArray(id: (int) $id, object: $data);
@@ -218,7 +218,7 @@ public function destroy(string|int $id, ObjectService $objectService, DirectoryS
$directoryService->listCatalog(['id' => $id, 'listed' => false]);
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$this->catalogMapper->delete($this->catalogMapper->find((int) $id));
diff --git a/lib/Controller/DirectoryController.php b/lib/Controller/DirectoryController.php
index 45f29771..234d3d4e 100644
--- a/lib/Controller/DirectoryController.php
+++ b/lib/Controller/DirectoryController.php
@@ -54,7 +54,7 @@ public function index(ObjectService $objectService, SearchService $searchService
unset($filters['_route']);
$fieldsToSearch = ['summary'];
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
@@ -85,7 +85,7 @@ public function index(ObjectService $objectService, SearchService $searchService
*/
public function show(string|int $id, ObjectService $objectService, DirectoryService $directoryService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
try {
@@ -129,14 +129,14 @@ public function update(string|int $id, ObjectService $objectService): JSONRespon
// Remove fields we should never post
unset($data['id']);
- foreach($data as $key => $value) {
- if(str_starts_with($key, '_')) {
+ foreach ($data as $key => $value) {
+ if (str_starts_with($key, '_')) {
unset($data[$key]);
}
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->listingMapper->updateFromArray(id: (int) $id, object: $data));
@@ -164,7 +164,7 @@ public function update(string|int $id, ObjectService $objectService): JSONRespon
*/
public function destroy(string|int $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$this->listingMapper->delete($this->listingMapper->find((int) $id));
@@ -192,7 +192,7 @@ public function destroy(string|int $id, ObjectService $objectService): JSONRespo
*/
public function synchronise(string|int $id, DirectoryService $directoryService, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
try {
diff --git a/lib/Controller/MetaDataController.php b/lib/Controller/MetaDataController.php
index d72812e8..00f262ea 100644
--- a/lib/Controller/MetaDataController.php
+++ b/lib/Controller/MetaDataController.php
@@ -54,7 +54,7 @@ public function index(ObjectService $objectService, SearchService $searchService
unset($filters['_route']);
$fieldsToSearch = ['title', 'description'];
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
@@ -86,7 +86,7 @@ public function index(ObjectService $objectService, SearchService $searchService
*/
public function show(string|int $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
try {
@@ -120,20 +120,20 @@ public function create(ObjectService $objectService, IURLGenerator $urlGenerator
unset($data['id']);
- foreach($data as $key => $value) {
- if(str_starts_with($key, '_')) {
+ foreach ($data as $key => $value) {
+ if (str_starts_with($key, '_')) {
unset($data[$key]);
}
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$object = $this->metaDataMapper->createFromArray(object: $data);
$id = $object->getId();
- if($object->getSource() === null) {
+ if ($object->getSource() === null) {
$source = $urlGenerator->getAbsoluteURL($urlGenerator->linkToRoute(routeName:"opencatalogi.metadata.show", arguments: ['id' => $id]));
$object->setSource($source);
$this->metaDataMapper->update($object);
@@ -153,10 +153,10 @@ public function create(ObjectService $objectService, IURLGenerator $urlGenerator
config: $dbConfig
);
- if(isset($data['source']) === false || $data['source'] === null) {
+ 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,
+ data: $returnData,
config: $dbConfig
);
}
@@ -175,13 +175,13 @@ public function update(string|int $id, ObjectService $objectService): JSONRespon
// Remove fields we should never post
unset($data['id'],$data['source']);
- foreach($data as $key => $value) {
- if(str_starts_with($key, '_')) {
+ foreach ($data as $key => $value) {
+ if (str_starts_with($key, '_')) {
unset($data[$key]);
}
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->metaDataMapper->updateFromArray(id: (int) $id, object: $data));
@@ -209,7 +209,7 @@ public function update(string|int $id, ObjectService $objectService): JSONRespon
*/
public function destroy(string|int $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$this->metaDataMapper->delete($this->metaDataMapper->find(id: (int) $id));
diff --git a/lib/Controller/OrganisationsController.php b/lib/Controller/OrganisationsController.php
index 2fe4bf06..c1fb1722 100644
--- a/lib/Controller/OrganisationsController.php
+++ b/lib/Controller/OrganisationsController.php
@@ -52,7 +52,7 @@ public function index(ObjectService $objectService, SearchService $searchService
unset($filters['_route']);
$fieldsToSearch = ['title', 'description', 'summary'];
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
@@ -92,7 +92,7 @@ public function index(ObjectService $objectService, SearchService $searchService
*/
public function show(string $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
try {
@@ -137,7 +137,7 @@ public function create(ObjectService $objectService): JSONResponse
unset($data[$key]);
}
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->organisationMapper->createFromArray(object: $data));
@@ -150,11 +150,14 @@ public function create(ObjectService $objectService): JSONResponse
'mongodbCluster' => $this->config->getValueString($this->appName, 'mongodbCluster')
];
- $filters['_schema'] = 'organisation';
+ $data['_schema'] = 'organisation';
- $result = $objectService->findObjects(filters: $filters, config: $dbConfig);
+ $returnData = $objectService->saveObject(
+ data: $data,
+ config: $dbConfig
+ );
- return new JSONResponse(["results" => $result['documents']]);
+ return new JSONResponse($returnData);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
@@ -181,7 +184,7 @@ public function update(string $id, ObjectService $objectService): JSONResponse
unset($data['id']);
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->organisationMapper->updateFromArray(id: (int) $id, object: $data));
@@ -213,7 +216,7 @@ public function update(string $id, ObjectService $objectService): JSONResponse
*/
public function destroy(string $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$this->organisationMapper->delete($this->organisationMapper->find((int) $id));
diff --git a/lib/Controller/PublicationsController.php b/lib/Controller/PublicationsController.php
index 97904af5..3264ef8d 100644
--- a/lib/Controller/PublicationsController.php
+++ b/lib/Controller/PublicationsController.php
@@ -46,9 +46,9 @@ public function __construct
private function insertNestedObjects(array $object, ObjectService $objectService, array $config): array
{
//@TODO keep in mind that unpublished objects should not be inserted, and that objects should be updated if a subobject is updated.
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
try {
- if(
+ if (
is_string(value: $value)
&& $key !== 'id'
&& Uuid::isValid(uuid: $value) === true
@@ -57,7 +57,7 @@ private function insertNestedObjects(array $object, ObjectService $objectService
$object[$key] = $subObject;
}
- if(
+ if (
is_array(value: $value) === true
&& array_is_list(array: $value) === true
) {
@@ -118,7 +118,7 @@ public function index(ObjectService $objectService, SearchService $searchService
unset($filters['_route']);
$fieldsToSearch = ['p.title', 'p.description', 'p.summary'];
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
@@ -469,8 +469,8 @@ public function create(ObjectService $objectService, ElasticSearchService $elast
// Remove fields we should never post
unset($data['id']);
- foreach($data as $key => $value) {
- if(str_starts_with($key, '_')) {
+ foreach ($data as $key => $value) {
+ if (str_starts_with($key, '_')) {
unset($data[$key]);
}
}
@@ -481,7 +481,7 @@ public function create(ObjectService $objectService, ElasticSearchService $elast
return new JSONResponse(data: ['message' => $exception->getMessage()], statusCode: 400);
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$returnData = $this->publicationMapper->createFromArray($data);
@@ -498,7 +498,7 @@ public function create(ObjectService $objectService, ElasticSearchService $elast
config: $dbConfig
);
}
- if(
+ if (
$this->config->hasKey(app: $this->appName, key: 'elasticLocation') === true
&& $this->config->getValueString(app: $this->appName, key: 'elasticLocation') !== ''
&& $this->config->hasKey(app: $this->appName, key: 'elasticKey') === true
@@ -532,13 +532,13 @@ public function update(string|int $id, ObjectService $objectService, ElasticSear
// Remove fields we should never post
unset($data['id']);
- foreach($data as $key => $value) {
- if(str_starts_with($key, '_')) {
+ foreach ($data as $key => $value) {
+ if (str_starts_with($key, '_')) {
unset($data[$key]);
}
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$returnData = $this->publicationMapper->updateFromArray(id: (int) $id, object: $data);
@@ -558,7 +558,7 @@ public function update(string|int $id, ObjectService $objectService, ElasticSear
);
}
- if(
+ if (
$this->config->hasKey(app: $this->appName, key: 'elasticLocation') === true
&& $this->config->getValueString(app: $this->appName, key: 'elasticLocation') !== ''
&& $this->config->hasKey(app: $this->appName, key: 'elasticKey') === true
@@ -587,7 +587,7 @@ public function update(string|int $id, ObjectService $objectService, ElasticSear
*/
public function destroy(string|int $id, ObjectService $objectService, ElasticSearchService $elasticSearchService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$this->publicationMapper->delete($this->publicationMapper->find(id: (int) $id));
@@ -605,7 +605,7 @@ public function destroy(string|int $id, ObjectService $objectService, ElasticSea
);
}
- if(
+ if (
$this->config->hasKey(app: $this->appName, key: 'elasticLocation') === true
&& $this->config->getValueString(app: $this->appName, key: 'elasticLocation') !== ''
&& $this->config->hasKey(app: $this->appName, key: 'elasticKey') === true
diff --git a/lib/Controller/SearchController.php b/lib/Controller/SearchController.php
index 9da7418a..6341bfce 100644
--- a/lib/Controller/SearchController.php
+++ b/lib/Controller/SearchController.php
@@ -2,6 +2,7 @@
namespace OCA\OpenCatalogi\Controller;
+use GuzzleHttp\Exception\GuzzleException;
use OCA\OpenCatalogi\Service\ElasticSearchService;
use OCA\OpenCatalogi\Db\PublicationMapper;
use OCA\OpenCatalogi\Service\SearchService;
@@ -79,13 +80,15 @@ public function page(?string $getParameter)
);
}
- /**
- * @CORS
- * @PublicPage
- * @NoCSRFRequired
- */
- public function index(SearchService $searchService): JSONResponse
- {
+ /**
+ * The Index function.
+ *
+ * @param SearchService $searchService The Search Service.
+ *
+ * @return JSONResponse The Response.
+ */
+ private function searchIndex(SearchService $searchService): JSONResponse
+ {
$elasticConfig['location'] = $this->config->getValueString(app: $this->appName, key: 'elasticLocation');
$elasticConfig['key'] = $this->config->getValueString(app: $this->appName, key: 'elasticKey');
$elasticConfig['index'] = $this->config->getValueString(app: $this->appName, key: 'elasticIndex');
@@ -97,12 +100,12 @@ public function index(SearchService $searchService): JSONResponse
$filters = $this->request->getParams();
unset($filters['_route']);
- // Status must be always published when searching for publications
- $filters['status'] = 'published';
+ // Status must be always published when searching for publications
+ $filters['status'] = 'published';
- $fieldsToSearch = ['p.title', 'p.description', 'p.summary'];
+ $fieldsToSearch = ['p.title', 'p.description', 'p.summary'];
- if($this->config->hasKey($this->appName, 'elasticLocation') === false
+ if ($this->config->hasKey($this->appName, 'elasticLocation') === false
|| $this->config->getValueString($this->appName, 'elasticLocation') === ''
) {
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
@@ -112,12 +115,12 @@ public function index(SearchService $searchService): JSONResponse
$offset = 0;
$page = 0;
- if(isset($filters['_limit']) === true) {
- $limit = $filters['_limit'];
+ if (isset($filters['_limit']) === true) {
+ $limit = (int) $filters['_limit'];
}
if (isset($filters['_page']) === true) {
- $page = $filters['_page'];
+ $page = (int) $filters['_page'];
$offset = ($limit * ($filters['_page'] - 1));
}
@@ -150,90 +153,6 @@ public function index(SearchService $searchService): JSONResponse
$filters = array_combine(keys: $keys, values: $values);
- $requiredElasticConfig = ['location', 'key', 'index'];
- $missingFields = null;
- foreach ($requiredElasticConfig as $key) {
- if (isset($elasticConfig[$key]) === false || empty($elasticConfig[$key])) {
- $missingFields .= "$key, ";
- }
- }
-
- if ($missingFields !== null) {
- $errorMessage = "Missing the following elastic configuration: {$missingFields}please update your elastic connection in application settings.";
- $response = new JSONResponse(data: ['code' => 403, 'message' => $errorMessage], statusCode: 403);
-
- return $response;
- }
-
- $data = $searchService->search(parameters: $filters, elasticConfig: $elasticConfig, dbConfig: $dbConfig);
-
- return new JSONResponse($data);
- }
-
- /**
- * @PublicPage
- * @NoCSRFRequired
- */
- public function indexInternal(SearchService $searchService): JSONResponse
- {
- $elasticConfig['location'] = $this->config->getValueString(app: $this->appName, key: 'elasticLocation');
- $elasticConfig['key'] = $this->config->getValueString(app: $this->appName, key: 'elasticKey');
- $elasticConfig['index'] = $this->config->getValueString(app: $this->appName, key: 'elasticIndex');
-
- $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 = $this->request->getParams();
- unset($filters['_route']);
-
- // Status must be always published when searching for publications
- $filters['status'] = 'published';
-
- $fieldsToSearch = ['p.title', 'p.description', 'p.summary'];
-
- if($this->config->hasKey($this->appName, 'elasticLocation') === false
- || $this->config->getValueString($this->appName, 'elasticLocation') === ''
- ) {
- $searchParams = $searchService->createMySQLSearchParams(filters: $filters);
- $searchConditions = $searchService->createMySQLSearchConditions(filters: $filters, fieldsToSearch: $fieldsToSearch, searchParams: $searchParams);
-
- $limit = 30;
- $offset = 0;
-
- if(isset($filters['_limit']) === true) {
- $limit = $filters['_limit'];
- }
-
- if(isset($filters['_page']) === true) {
- $offset = ($limit * ($filters['_page'] - 1));
- }
-
- $filters = $searchService->unsetSpecialQueryParams(filters: $filters);
-
- $total = $this->publicationMapper->count($filters);
- $results = $this->publicationMapper->findAll(limit: $limit, offset: $offset, filters: $filters, searchConditions: $searchConditions, searchParams: $searchParams);
- $pages = (int) ceil($total / $limit);
-
- return new JSONResponse([
- 'results' => $results,
- 'facets' => [],
- 'count' => count($results),
- 'limit' => $limit,
- 'page' => isset($filters['_page']) === true ? $filters['_page'] : 1,
- 'pages' => $pages === 0 ? 1 : $pages,
- 'total' => $total
- ]);
- }
-
- //@TODO: find a better way to get query params. This fixes it for now.
- $keys = array_keys(array: $filters);
- $values = array_values(array: $filters);
-
- $keys = str_replace('_', '.', $keys);
-
- $filters = array_combine(keys: $keys, values: $values);
-
$requiredElasticConfig = ['location', 'key', 'index'];
$missingFields = null;
foreach ($requiredElasticConfig as $key) {
@@ -255,19 +174,43 @@ public function indexInternal(SearchService $searchService): JSONResponse
}
+ /**
+ * @CORS
+ * @PublicPage
+ * @NoCSRFRequired
+ */
+ public function index(SearchService $searchService): JSONResponse
+ {
+ return $this->searchIndex(searchService: $searchService);
+ }
/**
- * @CORS
* @PublicPage
* @NoCSRFRequired
*/
- public function show(string|int $id, SearchService $searchService, ObjectService $objectService): JSONResponse
+ public function indexInternal(SearchService $searchService): JSONResponse
+ {
+ return $this->searchIndex(searchService: $searchService);
+ }
+
+
+ /**
+ * The Show function.
+ *
+ * @param string|int $id The id.
+ * @param SearchService $searchService The Search Service.
+ * @param ObjectService $objectService The Object Service.
+ *
+ * @return JSONResponse The response.
+ * @throws GuzzleException
+ */
+ private function searchShow(string|int $id, SearchService $searchService, ObjectService $objectService): JSONResponse
{
$elasticConfig['location'] = $this->config->getValueString(app: $this->appName, key: 'elasticLocation');
$elasticConfig['key'] = $this->config->getValueString(app: $this->appName, key: 'elasticKey');
$elasticConfig['index'] = $this->config->getValueString(app: $this->appName, key: 'elasticIndex');
- if($this->config->hasKey($this->appName, 'elasticLocation') === false
+ if ($this->config->hasKey($this->appName, 'elasticLocation') === false
|| $this->config->getValueString($this->appName, 'elasticLocation') === ''
) {
if ($this->config->hasKey($this->appName, 'mongoStorage') === false
@@ -276,7 +219,7 @@ public function show(string|int $id, SearchService $searchService, ObjectService
try {
$object = $this->publicationMapper->find(id: (int) $id);
- if($object->getStatus() === 'published') {
+ if ($object->getStatus() === 'published') {
return new JSONResponse($object->jsonSerialize());
}
throw new DoesNotExistException('object not published');
@@ -317,14 +260,22 @@ public function show(string|int $id, SearchService $searchService, ObjectService
$data = $searchService->search(parameters: $filters, elasticConfig: $elasticConfig, dbConfig: $dbConfig);
- if(count($data['results']) > 0) {
+ if (count($data['results']) > 0) {
return new JSONResponse($data['results'][0]);
}
return new JSONResponse(data: ['error' => ['code' => 404, 'message' => 'the requested resource could not be found']], statusCode: 404);
}
-
+ /**
+ * @CORS
+ * @PublicPage
+ * @NoCSRFRequired
+ */
+ public function show(string|int $id, SearchService $searchService, ObjectService $objectService): JSONResponse
+ {
+ return $this->searchShow(id: $id, searchService: $searchService, objectService: $objectService);
+ }
/**
* @PublicPage
@@ -332,65 +283,7 @@ public function show(string|int $id, SearchService $searchService, ObjectService
*/
public function showInternal(string|int $id, SearchService $searchService, ObjectService $objectService): JSONResponse
{
- $elasticConfig['location'] = $this->config->getValueString(app: $this->appName, key: 'elasticLocation');
- $elasticConfig['key'] = $this->config->getValueString(app: $this->appName, key: 'elasticKey');
- $elasticConfig['index'] = $this->config->getValueString(app: $this->appName, key: 'elasticIndex');
-
- if($this->config->hasKey($this->appName, 'elasticLocation') === false
- || $this->config->getValueString($this->appName, 'elasticLocation') === ''
- ) {
- if ($this->config->hasKey($this->appName, 'mongoStorage') === false
- || $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
- ) {
- try {
- $object = $this->publicationMapper->find(id: (int) $id);
-
- if($object->getStatus() === 'published') {
- return new JSONResponse($object->jsonSerialize());
- }
- throw new DoesNotExistException('object not published');
- } catch (DoesNotExistException $exception) {
- return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404);
- }
- }
-
- $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;
-
- $result = $objectService->findObject(filters: $filters, config: $dbConfig);
-
- return new JSONResponse($result);
- }
-
- $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];
-
- $requiredElasticConfig = ['location', 'key', 'index'];
- $missingFields = null;
- foreach ($requiredElasticConfig as $key) {
- if (isset($elasticConfig[$key]) === false) {
- $missingFields .= "$key ";
- }
- }
-
- if ($missingFields !== null) {
- $errorMessage = "Missing the following elastic configuration: {$missingFields}please update your elastic connection in application settings.";
- return new JSONResponse(['message' => $errorMessage], 403);
- }
-
- $data = $searchService->search(parameters: $filters, elasticConfig: $elasticConfig, dbConfig: $dbConfig);
-
- if(count($data['results']) > 0) {
- return new JSONResponse($data['results'][0]);
- }
-
- return new JSONResponse(data: ['error' => ['code' => 404, 'message' => 'the requested resource could not be found']], statusCode: 404);
+ return $this->searchShow(id: $id, searchService: $searchService, objectService: $objectService);
}
}
diff --git a/lib/Controller/ThemesController.php b/lib/Controller/ThemesController.php
index 9d98d37a..160b64ef 100644
--- a/lib/Controller/ThemesController.php
+++ b/lib/Controller/ThemesController.php
@@ -2,6 +2,7 @@
namespace OCA\OpenCatalogi\Controller;
+use GuzzleHttp\Exception\GuzzleException;
use OCA\OpenCatalogi\Db\ThemeMapper;
use OCA\OpenCatalogi\Service\ObjectService;
use OCA\OpenCatalogi\Service\SearchService;
@@ -40,20 +41,21 @@ public function page(): TemplateResponse
}
/**
- * Return (and serach) all objects
+ * The Index function.
*
- * @NoAdminRequired
- * @NoCSRFRequired
+ * @param ObjectService $objectService The Object service.
+ * @param SearchService $searchService The Search service.
*
- * @return JSONResponse
+ * @return JSONResponse The Response.
+ * @throws GuzzleException
*/
- public function index(ObjectService $objectService, SearchService $searchService): JSONResponse
+ private function themesIndex(ObjectService $objectService, SearchService $searchService): JSONResponse
{
- $filters = $this->request->getParams();
+ $filters = $this->request->getParams();
unset($filters['_route']);
- $fieldsToSearch = ['title', 'description', 'summary'];
+ $fieldsToSearch = ['title', 'description', 'summary'];
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
@@ -66,34 +68,72 @@ public function index(ObjectService $objectService, SearchService $searchService
$filters = $searchService->createMongoDBSearchFilter(filters: $filters, fieldsToSearch: $fieldsToSearch);
$filters = $searchService->unsetSpecialQueryParams(filters: $filters);
- 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')
- ];
+ 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')
+ ];
- $filters['_schema'] = 'theme';
+ $filters['_schema'] = 'theme';
- $result = $objectService->findObjects(filters: $filters, config: $dbConfig);
+ $result = $objectService->findObjects(filters: $filters, config: $dbConfig);
- return new JSONResponse(["results" => $result['documents']]);
- } catch (\Exception $e) {
- return new JSONResponse(['error' => $e->getMessage()], 500);
- }
+ return new JSONResponse(["results" => $result['documents']]);
+ } catch (\Exception $e) {
+ return new JSONResponse(['error' => $e->getMessage()], 500);
+ }
}
/**
- * Read a single object
+ * Return (and serach) all objects
*
+ * @CORS
+ * @PublicPage
* @NoAdminRequired
* @NoCSRFRequired
*
- * @return JSONResponse
+ * @param ObjectService $objectService The Object service.
+ * @param SearchService $searchService The Search service.
+ *
+ * @return JSONResponse The Response.
+ * @throws GuzzleException
*/
- public function show(string $id, ObjectService $objectService): JSONResponse
+ public function index(ObjectService $objectService, SearchService $searchService): JSONResponse
+ {
+ return $this->themesIndex($objectService, $searchService);
+ }
+
+ /**
+ * Return (and serach) all objects
+ *
+ * @PublicPage
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @param ObjectService $objectService The Object service.
+ * @param SearchService $searchService The Search service.
+ *
+ * @return JSONResponse The Response.
+ * @throws GuzzleException
+ */
+ public function indexInternal(ObjectService $objectService, SearchService $searchService): JSONResponse
+ {
+ return $this->themesIndex($objectService, $searchService);
+ }
+
+ /**
+ * The Show function.
+ *
+ * @param string $id The id.
+ * @param ObjectService $objectService The Object Service.
+ *
+ * @return JSONResponse The response.
+ * @throws GuzzleException
+ */
+ private function themesShow(string $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
try {
@@ -103,26 +143,63 @@ public function show(string $id, ObjectService $objectService): JSONResponse
}
}
- 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')
- ];
+ 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')
+ ];
- $filters['_id'] = (string) $id;
+ $filters['_id'] = (string) $id;
- $result = $objectService->findObject($filters, $dbConfig);
+ $result = $objectService->findObject($filters, $dbConfig);
- return new JSONResponse($result);
- } catch (\Exception $e) {
- return new JSONResponse(['error' => $e->getMessage()], 500);
- }
+ return new JSONResponse($result);
+ } catch (\Exception $e) {
+ return new JSONResponse(['error' => $e->getMessage()], 500);
+ }
+ }
+
+ /**
+ * Read a single object
+ *
+ * @CORS
+ * @PublicPage
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @param string $id The id.
+ * @param ObjectService $objectService The Object Service.
+ *
+ * @return JSONResponse The response.
+ * @throws GuzzleException
+ */
+ public function show(string $id, ObjectService $objectService): JSONResponse
+ {
+ return $this->themesShow($id, $objectService);
+ }
+
+ /**
+ * Read a single object
+ *
+ * @PublicPage
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @param string $id The id.
+ * @param ObjectService $objectService The Object Service.
+ *
+ * @return JSONResponse The response.
+ * @throws GuzzleException
+ */
+ public function showInternal(string $id, ObjectService $objectService): JSONResponse
+ {
+ return $this->themesShow($id, $objectService);
}
/**
- * Creatue an object
+ * Create an object
*
* @NoAdminRequired
* @NoCSRFRequired
@@ -139,7 +216,7 @@ public function create(ObjectService $objectService): JSONResponse
unset($data[$key]);
}
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->themeMapper->createFromArray(object: $data));
@@ -152,11 +229,14 @@ public function create(ObjectService $objectService): JSONResponse
'mongodbCluster' => $this->config->getValueString($this->appName, 'mongodbCluster')
];
- $filters['_schema'] = 'organisation';
+ $data['_schema'] = 'theme';
- $result = $objectService->findObjects(filters: $filters, config: $dbConfig);
+ $returnData = $objectService->saveObject(
+ data: $data,
+ config: $dbConfig
+ );
- return new JSONResponse(["results" => $result['documents']]);
+ return new JSONResponse($returnData);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
@@ -183,7 +263,7 @@ public function update(string $id, ObjectService $objectService): JSONResponse
unset($data['id']);
}
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->themeMapper->updateFromArray(id: (int) $id, object: $data));
@@ -215,7 +295,7 @@ public function update(string $id, ObjectService $objectService): JSONResponse
*/
public function destroy(string $id, ObjectService $objectService): JSONResponse
{
- if($this->config->hasKey($this->appName, 'mongoStorage') === false
+ if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
$this->themeMapper->delete($this->themeMapper->find((int) $id));
diff --git a/lib/Cron/DirectorySync.php b/lib/Cron/DirectorySync.php
index 3a2d0946..cb85f20f 100644
--- a/lib/Cron/DirectorySync.php
+++ b/lib/Cron/DirectorySync.php
@@ -7,7 +7,7 @@
use OCP\AppFramework\Utility\ITimeFactory;
/**
- *
+ *
* Docs: https://docs.nextcloud.com/server/latest/developer_manual/basics/backgroundjobs.html
*/
class DirectorySync extends TimedJob {
@@ -28,6 +28,6 @@ public function __construct(ITimeFactory $time, DirectoryService $directoryServi
protected function run($arguments) {
$this->directoryService->doCronSync();
}
-
-}
\ No newline at end of file
+
+}
diff --git a/lib/Db/Attachment.php b/lib/Db/Attachment.php
index c23e40fe..09a1041c 100644
--- a/lib/Db/Attachment.php
+++ b/lib/Db/Attachment.php
@@ -61,7 +61,7 @@ public function hydrate(array $object): self
{
$jsonFields = $this->getJsonFields();
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
if (in_array($key, $jsonFields) === true && $value === []) {
$value = null;
}
diff --git a/lib/Db/Catalog.php b/lib/Db/Catalog.php
index 938e5122..5697f25f 100644
--- a/lib/Db/Catalog.php
+++ b/lib/Db/Catalog.php
@@ -44,7 +44,7 @@ public function hydrate(array $object): self
{
$jsonFields = $this->getJsonFields();
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
if (in_array($key, $jsonFields) === true && $value === []) {
$value = [];
}
diff --git a/lib/Db/CatalogMapper.php b/lib/Db/CatalogMapper.php
index 71284aee..b4a3e2fc 100644
--- a/lib/Db/CatalogMapper.php
+++ b/lib/Db/CatalogMapper.php
@@ -37,7 +37,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters
->setMaxResults($limit)
->setFirstResult($offset);
- foreach($filters as $filter => $value) {
+ foreach ($filters as $filter => $value) {
if ($value === 'IS NOT NULL') {
$qb->andWhere($qb->expr()->isNotNull($filter));
} elseif ($value === 'IS NULL') {
diff --git a/lib/Db/Listing.php b/lib/Db/Listing.php
index 3bc89066..5417c21a 100644
--- a/lib/Db/Listing.php
+++ b/lib/Db/Listing.php
@@ -52,11 +52,11 @@ public function hydrate(array $object): self
{
$jsonFields = $this->getJsonFields();
- if(isset($object['metadata']) === false) {
+ if (isset($object['metadata']) === false) {
$object['metadata'] = [];
}
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
if (in_array($key, $jsonFields) === true && $value === []) {
$value = null;
}
diff --git a/lib/Db/MetaData.php b/lib/Db/MetaData.php
index d1e0c508..8135bb23 100644
--- a/lib/Db/MetaData.php
+++ b/lib/Db/MetaData.php
@@ -42,7 +42,7 @@ public function hydrate(array $object): self
{
$jsonFields = $this->getJsonFields();
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
if (in_array($key, $jsonFields) === true && $value === []) {
$value = null;
}
@@ -69,7 +69,7 @@ public function jsonSerialize(): array
}
switch ($property['format']) {
case 'string':
- // For now array as string
+ // For now array as string
case 'array':
$properties[$key]['default'] = (string) $property;
break;
diff --git a/lib/Db/MetaDataMapper.php b/lib/Db/MetaDataMapper.php
index 3bce0ac4..50ee05a0 100644
--- a/lib/Db/MetaDataMapper.php
+++ b/lib/Db/MetaDataMapper.php
@@ -37,7 +37,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters
->setMaxResults($limit)
->setFirstResult($offset);
- foreach($filters as $filter => $value) {
+ foreach ($filters as $filter => $value) {
if ($value === 'IS NOT NULL') {
$qb->andWhere($qb->expr()->isNotNull($filter));
} elseif ($value === 'IS NULL') {
diff --git a/lib/Db/Organisation.php b/lib/Db/Organisation.php
index fd168a89..67e8f3c1 100644
--- a/lib/Db/Organisation.php
+++ b/lib/Db/Organisation.php
@@ -43,7 +43,7 @@ public function hydrate(array $object): self
{
$jsonFields = $this->getJsonFields();
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
if (in_array($key, $jsonFields) === true && $value === []) {
$value = null;
}
diff --git a/lib/Db/OrganisationMapper.php b/lib/Db/OrganisationMapper.php
index 0701e61c..33ec35b0 100644
--- a/lib/Db/OrganisationMapper.php
+++ b/lib/Db/OrganisationMapper.php
@@ -37,7 +37,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters
->setMaxResults($limit)
->setFirstResult($offset);
- foreach($filters as $filter => $value) {
+ foreach ($filters as $filter => $value) {
if ($value === 'IS NOT NULL') {
$qb->andWhere($qb->expr()->isNotNull($filter));
} elseif ($value === 'IS NULL') {
diff --git a/lib/Db/Publication.php b/lib/Db/Publication.php
index 8813884b..631d9414 100644
--- a/lib/Db/Publication.php
+++ b/lib/Db/Publication.php
@@ -87,7 +87,7 @@ public function hydrate(array $object): self
$object['schema'] = $object['metaData'] ?? $this->getMetaData();
}
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
if (in_array($key, $jsonFields) === true && $value === []) {
$value = null;
}
@@ -102,7 +102,7 @@ public function hydrate(array $object): self
}
$this->setAttachmentCount('0');
- if($this->attachments !== null) {
+ if ($this->attachments !== null) {
$this->setAttachmentCount(count($this->getAttachments()));
}
diff --git a/lib/Db/PublicationMapper.php b/lib/Db/PublicationMapper.php
index d2ff7624..79cc0831 100644
--- a/lib/Db/PublicationMapper.php
+++ b/lib/Db/PublicationMapper.php
@@ -116,7 +116,7 @@ protected function findEntitiesCustom(IQueryBuilder $query): array {
private function parseComplexFilter(IQueryBuilder $queryBuilder, array $filter, string $name): IQueryBuilder
{
- foreach($filter as $key => $value) {
+ foreach ($filter as $key => $value) {
switch($key) {
case '>=':
case 'after':
@@ -144,8 +144,8 @@ private function parseComplexFilter(IQueryBuilder $queryBuilder, array $filter,
private function addFilters(IQueryBuilder $queryBuilder, array $filters): IQueryBuilder
{
- foreach($filters as $key => $filter) {
- if(is_array($filter) === false) {
+ foreach ($filters as $key => $filter) {
+ if (is_array($filter) === false) {
$queryBuilder->andWhere($queryBuilder->expr()->eq($key, $queryBuilder->createNamedParameter($filter)));
$queryBuilder->setParameter($key, $filter);
continue;
@@ -212,7 +212,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters
foreach ($searchConditions as $condition) {
$qb->andWhere($condition);
}
-
+
// Bind all parameters at once using setParameters()
$paramBindings = [];
foreach ($searchParams as $param => $value) {
@@ -224,7 +224,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters
$paramBindings[$param] = $value;
}
}
-
+
// Use setParameters to bind all at once
foreach ($paramBindings as $param => $binding) {
if (is_array($binding) === true) {
diff --git a/lib/Db/Theme.php b/lib/Db/Theme.php
index a8365809..14942b34 100644
--- a/lib/Db/Theme.php
+++ b/lib/Db/Theme.php
@@ -35,7 +35,7 @@ public function hydrate(array $object): self
{
$jsonFields = $this->getJsonFields();
- foreach($object as $key => $value) {
+ foreach ($object as $key => $value) {
if (in_array($key, $jsonFields) === true && $value === []) {
$value = null;
}
diff --git a/lib/Db/ThemeMapper.php b/lib/Db/ThemeMapper.php
index 561b30d4..e65d4fa0 100644
--- a/lib/Db/ThemeMapper.php
+++ b/lib/Db/ThemeMapper.php
@@ -37,7 +37,7 @@ public function findAll(?int $limit = null, ?int $offset = null, ?array $filters
->setMaxResults($limit)
->setFirstResult($offset);
- foreach($filters as $filter => $value) {
+ foreach ($filters as $filter => $value) {
if ($value === 'IS NOT NULL') {
$qb->andWhere($qb->expr()->isNotNull($filter));
} elseif ($value === 'IS NULL') {
diff --git a/lib/Flow/Operations/AutomatedPublishing.php b/lib/Flow/Operations/AutomatedPublishing.php
index 0cc3d10c..3e186027 100644
--- a/lib/Flow/Operations/AutomatedPublishing.php
+++ b/lib/Flow/Operations/AutomatedPublishing.php
@@ -24,15 +24,15 @@ public function validateOperation(): bool {
/**
* Determens for what kind of users the opertation is available
- *
+ *
* var $scope is presented from the IManager as a constant with 0 for ADMIN and 1 for USER
*/
public function isAvailableForScope(int $scope): bool {
- if(scope === 0){
+ if (scope === 0){
return false;
}
return false;
}
-}
\ No newline at end of file
+}
diff --git a/lib/Migration/Version6Date20240723125106.php b/lib/Migration/Version6Date20240723125106.php
index b04a1818..4b39b1c2 100644
--- a/lib/Migration/Version6Date20240723125106.php
+++ b/lib/Migration/Version6Date20240723125106.php
@@ -40,7 +40,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'publications') === false) {
+ if ($schema->hasTable(tableName: 'publications') === false) {
$table = $schema->createTable(tableName: 'publications');
$table->addColumn(name: 'id', typeName: Types::BIGINT, options: [
'autoincrement' => true,
diff --git a/lib/Migration/Version6Date20240724084920.php b/lib/Migration/Version6Date20240724084920.php
index 193a230c..7cca7301 100644
--- a/lib/Migration/Version6Date20240724084920.php
+++ b/lib/Migration/Version6Date20240724084920.php
@@ -40,7 +40,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'catalogi') === false) {
+ if ($schema->hasTable(tableName: 'catalogi') === false) {
$table = $schema->createTable(tableName: 'catalogi');
$table->addColumn(name: 'id', typeName: Types::BIGINT, options: [
'autoincrement' => true,
diff --git a/lib/Migration/Version6Date20240725114845.php b/lib/Migration/Version6Date20240725114845.php
index b4fcc63b..e451bb70 100644
--- a/lib/Migration/Version6Date20240725114845.php
+++ b/lib/Migration/Version6Date20240725114845.php
@@ -40,7 +40,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'metadata') === false) {
+ if ($schema->hasTable(tableName: 'metadata') === false) {
$table = $schema->createTable(tableName: 'metadata');
$table->addColumn(name: 'id', typeName: Types::BIGINT, options: [
'autoincrement' => true,
@@ -70,7 +70,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
}
- if($schema->hasTable(tableName: 'listings') === false) {
+ if ($schema->hasTable(tableName: 'listings') === false) {
$table = $schema->createTable(tableName: 'listings');
$table->addColumn(name: 'id', typeName: Types::BIGINT, options: [
'autoincrement' => true,
@@ -120,7 +120,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
}
- if($schema->hasTable(tableName: 'organizations') === false) {
+ if ($schema->hasTable(tableName: 'organizations') === false) {
$table = $schema->createTable(tableName: 'organizations');
$table->addColumn(name: 'id', typeName: Types::BIGINT, options: [
'autoincrement' => true,
@@ -159,7 +159,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
}
- if($schema->hasTable(tableName: 'attachments') === false) {
+ if ($schema->hasTable(tableName: 'attachments') === false) {
$table = $schema->createTable(tableName: 'attachments');
$table->addColumn(name: 'id', typeName: Types::BIGINT, options: [
'autoincrement' => true,
diff --git a/lib/Migration/Version6Date20240726122212.php b/lib/Migration/Version6Date20240726122212.php
index 604b4962..a047ecf0 100644
--- a/lib/Migration/Version6Date20240726122212.php
+++ b/lib/Migration/Version6Date20240726122212.php
@@ -40,10 +40,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'catalogi') === true) {
+ if ($schema->hasTable(tableName: 'catalogi') === true) {
$table = $schema->getTable(tableName: 'catalogi');
- if($table->hasColumn(name: 'reference')) {
+ if ($table->hasColumn(name: 'reference')) {
$table->dropColumn(name: 'reference');
}
diff --git a/lib/Migration/Version6Date20240726132348.php b/lib/Migration/Version6Date20240726132348.php
index 13dc10ca..0d0230f3 100644
--- a/lib/Migration/Version6Date20240726132348.php
+++ b/lib/Migration/Version6Date20240726132348.php
@@ -40,10 +40,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'publications') === true) {
+ if ($schema->hasTable(tableName: 'publications') === true) {
$table = $schema->getTable(tableName: 'publications');
- if($table->hasColumn(name: 'published') === false) {
+ if ($table->hasColumn(name: 'published') === false) {
$table->addColumn(name: 'published', typeName: Types::DATETIME);
}
diff --git a/lib/Migration/Version6Date20240726140008.php b/lib/Migration/Version6Date20240726140008.php
index 829e84fe..89f37a7a 100644
--- a/lib/Migration/Version6Date20240726140008.php
+++ b/lib/Migration/Version6Date20240726140008.php
@@ -39,10 +39,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'publications') === true) {
+ if ($schema->hasTable(tableName: 'publications') === true) {
$table = $schema->getTable(tableName: 'publications');
- if($table->hasColumn(name: 'publicationDate')) {
+ if ($table->hasColumn(name: 'publicationDate')) {
$table->dropColumn(name: 'publicationDate');
}
diff --git a/lib/Migration/Version6Date20240726140328.php b/lib/Migration/Version6Date20240726140328.php
index b2ed8e9f..3b0ea79f 100644
--- a/lib/Migration/Version6Date20240726140328.php
+++ b/lib/Migration/Version6Date20240726140328.php
@@ -39,10 +39,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'publications') === true) {
+ if ($schema->hasTable(tableName: 'publications') === true) {
$table = $schema->getTable(tableName: 'publications');
- if($table->hasColumn(name: 'publication_date')) {
+ if ($table->hasColumn(name: 'publication_date')) {
$table->dropColumn(name: 'publication_date');
}
diff --git a/lib/Migration/Version6Date20240731141731.php b/lib/Migration/Version6Date20240731141731.php
index b89799e8..3a02db4d 100644
--- a/lib/Migration/Version6Date20240731141731.php
+++ b/lib/Migration/Version6Date20240731141731.php
@@ -40,10 +40,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'listings') === true) {
+ if ($schema->hasTable(tableName: 'listings') === true) {
$table = $schema->getTable(tableName: 'listings');
- if($table->hasColumn(name: 'catalog_id') === false) {
+ if ($table->hasColumn(name: 'catalog_id') === false) {
$table->addColumn(name: 'catalog_id', typeName: Types::STRING);
}
}
diff --git a/lib/Migration/Version6Date20240806073229.php b/lib/Migration/Version6Date20240806073229.php
index 93cf243e..66cad10a 100644
--- a/lib/Migration/Version6Date20240806073229.php
+++ b/lib/Migration/Version6Date20240806073229.php
@@ -43,7 +43,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
/**
* Let build the themas tabsle
*/
- if($schema->hasTable(tableName: 'themas') === false) {
+ if ($schema->hasTable(tableName: 'themas') === false) {
$table = $schema->createTable(tableName: 'themas');
$table->addColumn(name: 'id', typeName: Types::BIGINT, options: [
@@ -67,7 +67,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
'notnull' => false,
]);
-
+
$table->setPrimaryKey(columnNames: ['id']);
}
diff --git a/lib/Migration/Version6Date20240806114939.php b/lib/Migration/Version6Date20240806114939.php
index 98a279f3..cba457dd 100644
--- a/lib/Migration/Version6Date20240806114939.php
+++ b/lib/Migration/Version6Date20240806114939.php
@@ -40,10 +40,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'catalogi') === true) {
+ if ($schema->hasTable(tableName: 'catalogi') === true) {
$table = $schema->getTable(tableName: 'catalogi');
- if($table->hasColumn(name: 'listed') === false) {
+ if ($table->hasColumn(name: 'listed') === false) {
$table->addColumn(name: 'listed', typeName: Types::BOOLEAN, options: ['notNull' => false, 'default' => false]);
}
diff --git a/lib/Migration/Version6Date20240808085441.php b/lib/Migration/Version6Date20240808085441.php
index c1a2bea2..382dd55d 100644
--- a/lib/Migration/Version6Date20240808085441.php
+++ b/lib/Migration/Version6Date20240808085441.php
@@ -40,10 +40,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'catalogi') === true) {
+ if ($schema->hasTable(tableName: 'catalogi') === true) {
$table = $schema->getTable(tableName: 'catalogi');
- if($table->hasColumn(name: 'organization') === false) {
+ if ($table->hasColumn(name: 'organization') === false) {
$table->addColumn(
name: 'organization',
typeName: Types::STRING,
@@ -52,7 +52,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
'default' => null
]);
}
- if($table->hasColumn(name: 'metadata') === false) {
+ if ($table->hasColumn(name: 'metadata') === false) {
$metadata = $table->addColumn(
name: 'metadata',
typeName: Types::JSON,
diff --git a/lib/Migration/Version6Date20240808092738.php b/lib/Migration/Version6Date20240808092738.php
index e5babbe7..197cbf5f 100644
--- a/lib/Migration/Version6Date20240808092738.php
+++ b/lib/Migration/Version6Date20240808092738.php
@@ -40,10 +40,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'publications') === true) {
+ if ($schema->hasTable(tableName: 'publications') === true) {
$table = $schema->getTable(tableName: 'publications');
- if($table->hasColumn(name: 'published') === true) {
+ if ($table->hasColumn(name: 'published') === true) {
$column = $table->getColumn(name: 'published');
$column->setDefault(default: null);
}
diff --git a/lib/Migration/Version6Date20240808093230.php b/lib/Migration/Version6Date20240808093230.php
index 81e9d2bc..4aeaf8df 100644
--- a/lib/Migration/Version6Date20240808093230.php
+++ b/lib/Migration/Version6Date20240808093230.php
@@ -39,10 +39,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'publications') === true) {
+ if ($schema->hasTable(tableName: 'publications') === true) {
$table = $schema->getTable(tableName: 'publications');
- if($table->hasColumn(name: 'published') === true) {
+ if ($table->hasColumn(name: 'published') === true) {
$column = $table->getColumn(name: 'published');
$column->setNotnull(notnull: false);
}
diff --git a/lib/Migration/Version6Date20240808115347.php b/lib/Migration/Version6Date20240808115347.php
index 4e60dccb..8b6f9a1d 100644
--- a/lib/Migration/Version6Date20240808115347.php
+++ b/lib/Migration/Version6Date20240808115347.php
@@ -40,13 +40,13 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'catalogi') === true) {
+ if ($schema->hasTable(tableName: 'catalogi') === true) {
$table = $schema->getTable(tableName: 'catalogi');
- if($table->hasColumn(name: 'organization') === true) {
+ if ($table->hasColumn(name: 'organization') === true) {
$column = $table->dropColumn('organization');
}
- if($table->hasColumn(name: 'organisation') === false) {
+ if ($table->hasColumn(name: 'organisation') === false) {
$table->addColumn(
name: 'organisation',
typeName: Types::STRING,
diff --git a/lib/Migration/Version6Date20240809120147.php b/lib/Migration/Version6Date20240809120147.php
index eb923ff0..b48e11a7 100644
--- a/lib/Migration/Version6Date20240809120147.php
+++ b/lib/Migration/Version6Date20240809120147.php
@@ -40,13 +40,13 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'listings') === true) {
+ if ($schema->hasTable(tableName: 'listings') === true) {
$table = $schema->getTable(tableName: 'listings');
- if($table->hasColumn(name: 'organization') === true) {
+ if ($table->hasColumn(name: 'organization') === true) {
$column = $table->dropColumn('organization');
}
- if($table->hasColumn(name: 'organisation') === false) {
+ if ($table->hasColumn(name: 'organisation') === false) {
$table->addColumn(
name: 'organisation',
typeName: Types::STRING,
@@ -54,7 +54,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
'notNull' => false,
'default' => null
]);
- $output->info('organisation should be added to listing');
+ $output->info('organisation should be added to listing');
}
}
diff --git a/lib/Migration/Version6Date20240809141351.php b/lib/Migration/Version6Date20240809141351.php
index 8f8563ee..8d6ea875 100644
--- a/lib/Migration/Version6Date20240809141351.php
+++ b/lib/Migration/Version6Date20240809141351.php
@@ -40,10 +40,10 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'metadata') === true) {
+ if ($schema->hasTable(tableName: 'metadata') === true) {
$table = $schema->getTable(tableName: 'metadata');
- if($table->hasColumn(name: 'source') === false) {
+ if ($table->hasColumn(name: 'source') === false) {
$table->addColumn(
name: 'source',
typeName: Types::STRING,
diff --git a/lib/Migration/Version6Date20240816084024.php b/lib/Migration/Version6Date20240816084024.php
index 52476108..da41a43a 100644
--- a/lib/Migration/Version6Date20240816084024.php
+++ b/lib/Migration/Version6Date20240816084024.php
@@ -40,18 +40,18 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'listings') === true) {
+ if ($schema->hasTable(tableName: 'listings') === true) {
$table = $schema->getTable(tableName: 'listings');
- if($table->hasColumn(name: 'reference') === true) {
+ if ($table->hasColumn(name: 'reference') === true) {
$table->dropColumn(name: 'reference');
}
}
- if($schema->hasTable(tableName: 'metadata') === true) {
+ if ($schema->hasTable(tableName: 'metadata') === true) {
$table = $schema->getTable(tableName: 'metadata');
- if($table->hasColumn(name: 'summary') === false) {
+ if ($table->hasColumn(name: 'summary') === false) {
$column = $table->addColumn(name: 'summary', typeName: Types::STRING);
$column->setNotnull(notnull: false)->setDefault(default: null);
}
diff --git a/lib/Migration/Version6Date20240816111746.php b/lib/Migration/Version6Date20240816111746.php
index 5acf0d18..06f2b304 100644
--- a/lib/Migration/Version6Date20240816111746.php
+++ b/lib/Migration/Version6Date20240816111746.php
@@ -40,18 +40,18 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'listings') === true) {
+ if ($schema->hasTable(tableName: 'listings') === true) {
$table = $schema->getTable(tableName: 'listings');
- if($table->hasColumn(name: 'status_code') === false) {
+ if ($table->hasColumn(name: 'status_code') === false) {
$table->addColumn(name: 'status_code', typeName: Types::INTEGER)->setNotnull(notnull: false);
}
}
- if($schema->hasTable(tableName: 'metadata') === true) {
+ if ($schema->hasTable(tableName: 'metadata') === true) {
$table = $schema->getTable(tableName: 'metadata');
- if($table->hasColumn(name: 'archive') === false) {
+ if ($table->hasColumn(name: 'archive') === false) {
$column = $table->addColumn(name: 'archive', typeName: Types::JSON);
$column->setNotnull(notnull: false)->setDefault(default: null);
}
diff --git a/lib/Migration/Version6Date20240816115114.php b/lib/Migration/Version6Date20240816115114.php
index 3c198963..b29dcd88 100644
--- a/lib/Migration/Version6Date20240816115114.php
+++ b/lib/Migration/Version6Date20240816115114.php
@@ -39,15 +39,15 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
*/
$schema = $schemaClosure();
- if($schema->hasTable(tableName: 'listings') === true) {
+ if ($schema->hasTable(tableName: 'listings') === true) {
$table = $schema->getTable(tableName: 'listings');
- if($table->hasColumn(name: 'status_code') === true) {
+ if ($table->hasColumn(name: 'status_code') === true) {
$table->getColumn(name: 'status_code')->setNotnull(notnull: false)->setDefault(default: null);
$output->info("Updated 'status_code' column to listings table as nullable with default null");
}
}
-
+
return $schema;
}
diff --git a/lib/Migration/Version6Date20240923093806.php b/lib/Migration/Version6Date20240923093806.php
new file mode 100644
index 00000000..6ec7d277
--- /dev/null
+++ b/lib/Migration/Version6Date20240923093806.php
@@ -0,0 +1,108 @@
+hasTable(tableName: 'publications') === true) {
+ $table = $schema->getTable(tableName: 'publications');
+ if($table->hasColumn(name: 'description') === true) {
+ $column = $table->getColumn(name: 'description');
+ $column->setLength(length: 20000);
+ }
+ }
+
+ if($schema->hasTable(tableName: 'attachments') === true) {
+ $table = $schema->getTable(tableName: 'attachments');
+ if($table->hasColumn(name: 'description') === true) {
+ $column = $table->getColumn(name: 'description');
+ $column->setLength(length: 20000);
+ }
+ }
+
+ if($schema->hasTable(tableName: 'catalogi') === true) {
+ $table = $schema->getTable(tableName: 'catalogi');
+ if($table->hasColumn(name: 'description') === true) {
+ $column = $table->getColumn(name: 'description');
+ $column->setLength(length: 20000);
+ }
+ }
+
+ if($schema->hasTable(tableName: 'listings') === true) {
+ $table = $schema->getTable(tableName: 'listings');
+ if($table->hasColumn(name: 'description') === true) {
+ $column = $table->getColumn(name: 'description');
+ $column->setLength(length: 20000);
+ }
+ }
+
+ if($schema->hasTable(tableName: 'metadata') === true) {
+ $table = $schema->getTable(tableName: 'metadata');
+ if($table->hasColumn(name: 'description') === true) {
+ $column = $table->getColumn(name: 'description');
+ $column->setLength(length: 20000);
+ }
+ }
+
+ if($schema->hasTable(tableName: 'organisations') === true) {
+ $table = $schema->getTable(tableName: 'organisations');
+ if($table->hasColumn(name: 'description') === true) {
+ $column = $table->getColumn(name: 'description');
+ $column->setLength(length: 20000);
+ }
+ }
+
+ if($schema->hasTable(tableName: 'themes') === true) {
+ $table = $schema->getTable(tableName: 'themes');
+ if($table->hasColumn(name: 'description') === true) {
+ $column = $table->getColumn(name: 'description');
+ $column->setLength(length: 20000);
+ }
+ }
+
+ 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 a4f3c842..2acd58cb 100644
--- a/lib/Service/DirectoryService.php
+++ b/lib/Service/DirectoryService.php
@@ -47,12 +47,12 @@ private function getDirectoryEntry(string $catalogId): array
public function registerToExternalDirectory (array $newDirectory = [], ?string $url = null, array &$externalDirectories = []): int
{
- if($newDirectory !== [] && $url === null) {
+ if ($newDirectory !== [] && $url === null) {
$url = $newDirectory['directory'];
}
- if($this->config->getValueString(app: $this->appName, key: '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');
@@ -62,13 +62,13 @@ public function registerToExternalDirectory (array $newDirectory = [], ?string $
$catalogi = $this->objectService->findObjects(filters: ['_schema' => 'directory'], config: $dbConfig)['documents'];
}
- foreach($catalogi as $catalog) {
- if($catalog instanceof Listing) {
+ foreach ($catalogi as $catalog) {
+ if ($catalog instanceof Listing) {
$catalog = $catalog->jsonSerialize();
}
unset($catalog['_id'], $catalog['id'], $catalog['_schema']);
- if($catalog['directory'] !== $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index"))) {
+ if ($catalog['directory'] !== $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index"))) {
continue;
}
@@ -77,7 +77,7 @@ public function registerToExternalDirectory (array $newDirectory = [], ?string $
$externalDirectories = $this->fetchFromExternalDirectory(url: $url, update: true);
- if($result !== null) {
+ if ($result !== null) {
return $result->getStatusCode();
}
return 200;
@@ -90,7 +90,7 @@ private function createDirectoryFromResult(array $result, bool $update = false):
$myDirectory = $this->getDirectoryEntry(catalogId: '');
- if(
+ if (
isset($result['directory']) === false
|| $result['directory'] === $myDirectory['directory']
|| (
@@ -102,21 +102,21 @@ private function createDirectoryFromResult(array $result, bool $update = false):
} else if (count($this->listDirectory(filters: ['catalogId' => $result['catalogId'], 'directory' => $result['directory']])) > 0 && $update === true) {
$listing = $this->listDirectory(filters: ['catalogId' => $result['catalogId'], 'directory' => $result['directory']])[0];
- if($listing instanceof Listing) {
+ if ($listing instanceof Listing) {
$listing = $listing->jsonSerialize();
}
$id = $listing['id'];
}
- if($this->config->getValueString($this->appName, 'mongoStorage') === '1') {
+ if ($this->config->getValueString($this->appName, 'mongoStorage') === '1') {
$dbConfig['base_uri'] = $this->config->getValueString(app: 'opencatalogi', key: 'mongodbLocation');
$dbConfig['headers']['api-key'] = $this->config->getValueString(app: 'opencatalogi', key: 'mongodbKey');
$dbConfig['mongodbCluster'] = $this->config->getValueString(app: 'opencatalogi', key: 'mongodbCluster');
$result['_schema'] = 'directory';
- if(isset($id) === true) {
+ if (isset($id) === true) {
$this->objectService->updateObject(
filters: ['id' => $id],
update: $result,
@@ -129,21 +129,49 @@ private function createDirectoryFromResult(array $result, bool $update = false):
config: $dbConfig
);
} else {
- if(isset($id) === true) {
+ if (isset($id) === true) {
return $this->listingMapper->updateFromArray(id: $id, object: $result)->jsonSerialize();
}
return $this->listingMapper->createFromArray(object: $result)->jsonSerialize();
}
}
+ /**
+ * array_map function for fetching a directory for a listing.
+ *
+ * @param Listing $listing
+ * @return string
+ */
+ private function getDirectory(Listing $listing): string
+ {
+ return $listing->getDirectory();
+ }
+
+ /**
+ * Get all directories to scan.
+ *
+ * @return array
+ */
+ private function getDirectories(): array
+ {
+ $listings = $this->listingMapper->findAll();
+
+ $directories = array_map(callback: [$this, 'getDirectory'], array: $listings);
+
+ return array_unique(array: $directories);
+ }
+
+ /**
+ * Run a synchronisation based on cron
+ *
+ * @return array
+ */
public function doCronSync(): array {
$results = [];
- $directories = [];
- //@todo get unique direcotries form the database
- $directories[] = 'https://directory.opencatalogi.nl/apps/opencatalogi/api/directory';
- foreach($directories as $key -> $directory){
- $result = $this->fetchFromExternalDirectory([], $directory, true);
+ $directories = $this->getDirectories();
+ foreach ($directories as $key=>$directory){
+ $result = $this->fetchFromExternalDirectory(url: $directory, update: true);
$results = array_merge_recursive($results, $result);
}
@@ -153,21 +181,34 @@ public function doCronSync(): array {
// Get or update the data for an specifi exernal directory
public function fetchFromExternalDirectory(array $directory = [], ?string $url = null, bool $update = false): array
{
- if($directory !== [] && $url === null) {
+ if ($directory !== [] && $url === null) {
$url = $directory['directory'];
}
$result = $this->client->get(uri: $url);
- if(str_contains(haystack: $result->getHeader('Content-Type')[0], needle: 'application/json') === false) {
- $result = $this->client->get(uri: rtrim(string: $url, characters: '/').'/apps/opencatalogi/api/directory');
+ if (str_contains(haystack: $result->getHeader('Content-Type')[0], needle: 'application/json') === false) {
+ $url = rtrim(string: $url, characters: '/').'/apps/opencatalogi/api/directory';
+ $result = $this->client->get(uri: $url);
}
$results = json_decode(json: $result->getBody()->getContents(), associative: true);
$addedDirectories = [];
+ $catalogs = [];
- foreach($results['results'] as $record) {
+ foreach ($results['results'] as $record) {
+ $catalogs[] = $record['catalogId'];
$addedDirectories[] = $this->createDirectoryFromResult(result: $record, update: $update);
+
+ }
+
+
+ $localListings = $this->listingMapper->findAll(filters: ['directory' => $url]);
+
+ foreach ($localListings as $localListing) {
+ if (in_array(needle: $localListing->getCatalogId(), haystack: $catalogs) === false) {
+ $this->listingMapper->delete($localListing);
+ }
}
return $addedDirectories;
@@ -199,12 +240,12 @@ public function listDirectory(array $filters = [], int $limit = 30, int $offset
public function deleteListing(string $catalogId, string $directoryUrl): void
{
- if($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
+ 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) {
+ foreach ($results as $result) {
$this->listingMapper->delete(entity: $result);
}
@@ -218,7 +259,7 @@ public function deleteListing(string $catalogId, string $directoryUrl): void
$results = $this->objectService->findObjects(filters: ['directory' => $directoryUrl, 'catalogId' => $catalogId, '_schema' => 'directory'], config: $dbConfig);
- foreach($results['documents'] as $result) {
+ foreach ($results['documents'] as $result) {
$this->objectService->deleteObject(filters: ['_id' => $result['_id']], config: $dbConfig);
}
@@ -229,14 +270,14 @@ public function directoryExists(string $catalogId, ?array &$listing = null): boo
{
$directoryUrl = $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index"));
- if($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
+ 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]);
$result = count($results) > 0;
- if($result === true) {
+ if ($result === true) {
$listing = $results[0]->jsonSerialize();
}
return $result;
@@ -252,7 +293,7 @@ public function directoryExists(string $catalogId, ?array &$listing = null): boo
$result = count(value: $results['documents']) > 0;
- if($result === true) {
+ if ($result === true) {
$listing = $results['documents'][0];
}
@@ -264,7 +305,7 @@ public function listCatalog (array $catalog): array
$existingListing = null;
$catalogId = $catalog['id'];
- if($catalog['listed'] === false) {
+ if ($catalog['listed'] === false) {
$this->deleteListing(catalogId: $catalogId, directoryUrl: $this->urlGenerator->getAbsoluteURL(url: $this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index")),);
return $catalog;
}
@@ -278,10 +319,10 @@ public function listCatalog (array $catalog): array
$listing['organisation'] = $catalog['organisation'];
$listing['metadata'] = $catalog['metadata'];
- if($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
+ if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
|| $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1'
) {
- if($this->directoryExists(catalogId: $catalogId, listing: $existingListing) === true) {
+ if ($this->directoryExists(catalogId: $catalogId, listing: $existingListing) === true) {
$listing = $this->listingMapper->updateFromArray(id: $existingListing['id'], object: $listing);
} else {
$listing = $this->listingMapper->createFromArray(object: $listing);
@@ -299,7 +340,7 @@ public function listCatalog (array $catalog): array
$listing['_schema'] = 'directory';
- if($this->directoryExists(catalogId: $catalogId, listing: $existingListing) === true) {
+ if ($this->directoryExists(catalogId: $catalogId, listing: $existingListing) === true) {
$returnData = $this->objectService->updateObject(filters: ['id' => $existingListing['id']], update: $listing, config: $dbConfig);
} else {
$returnData = $this->objectService->saveObject(data: $listing, config: $dbConfig);
diff --git a/lib/Service/ElasticSearchService.php b/lib/Service/ElasticSearchService.php
index 3f0be4a7..cb4e67cc 100644
--- a/lib/Service/ElasticSearchService.php
+++ b/lib/Service/ElasticSearchService.php
@@ -35,7 +35,7 @@ public function addObject(array $object, array $config): array
{
$client = $this->getClient(config: $config);
- if(isset($object['_id']) === true) {
+ if (isset($object['_id']) === true) {
unset($object['_id']);
}
@@ -75,7 +75,7 @@ public function updateObject(string $id, array $object, array $config): array
{
$client = $this->getClient(config: $config);
- if(isset($object['_id']) === true) {
+ if (isset($object['_id']) === true) {
unset($object['_id']);
}
@@ -94,15 +94,15 @@ public function updateObject(string $id, array $object, array $config): array
public function parseFilter(string $name, array|string $filter): array
{
- if(is_array($filter) === false) {
+ if (is_array($filter) === false) {
return ['match' => [$name => $filter]];
}
- foreach($filter as $key => $value) {
+ foreach ($filter as $key => $value) {
switch($key) {
case 'regexp':
case 'like':
- if(preg_match("/^\/.+\/[a-z]*$/i", $value) !== false) {
+ if (preg_match("/^\/.+\/[a-z]*$/i", $value) !== false) {
return ['regexp' => [$name => strtolower($value)]];
} else {
return ['match' => [$name => $value]];
@@ -137,18 +137,18 @@ public function parseFilters (array $filters): array
]
];
- if(isset($filters['.search']) === true) {
+ if (isset($filters['.search']) === true) {
$body['query']['bool']['must'][] = ['query_string' => ['query' => '*'.$filters['.search'].'*']];
}
- if(isset($filters['.queries']) === true) {
- foreach($filters['.queries'] as $query) {
+ if (isset($filters['.queries']) === true) {
+ foreach ($filters['.queries'] as $query) {
$body['runtime_mappings'][$query] = ['type' => 'keyword'];
$body['aggs'][$query] = ['terms' => ['field' => $query]];
}
}
- if(isset($filters['.catalogi']) === true) {
+ if (isset($filters['.catalogi']) === true) {
$body['query']['bool']['must'][] = [
'match' => [
'catalogi._id' => [
@@ -159,13 +159,13 @@ public function parseFilters (array $filters): array
];
}
- if(isset($filters['.limit']) === true) {
+ if (isset($filters['.limit']) === true) {
$body['size'] = (int) $filters['.limit'];
unset($filters['.limit']);
}
- if(isset($filters['.page']) === true) {
- if(isset($body['size']) === true) {
+ if (isset($filters['.page']) === true) {
+ if (isset($body['size']) === true) {
$body['from'] = $body['size'] * ($filters['.page'] - 1);
}
unset($filters['.page']);
@@ -238,7 +238,7 @@ public function searchObject(array $filters, array $config, int &$totalResults =
$totalResults = $result['hits']['total']['value'];
$return = ['results' => array_map(callback: [$this, 'formatResults'], array: $result['hits']['hits'])];
- if(isset($result['aggregations']) === true) {
+ if (isset($result['aggregations']) === true) {
$return['facets'] = array_map([$this, 'mapAggregationResults'], $result['aggregations']);
} else {
$return['facets'] = [];
diff --git a/lib/Service/SearchService.php b/lib/Service/SearchService.php
index 8a1d4a37..42d2b834 100644
--- a/lib/Service/SearchService.php
+++ b/lib/Service/SearchService.php
@@ -30,13 +30,13 @@ public function mergeFacets(array $existingAggregation, array $newAggregation):
$existingAggregationMapped = [];
$newAggregationMapped = [];
- foreach($existingAggregation as $value) {
+ foreach ($existingAggregation as $value) {
$existingAggregationMapped[$value['_id']] = $value['count'];
}
- foreach($newAggregation as $value) {
- if(isset ($existingAggregationMapped[$value['_id']]) === true) {
+ foreach ($newAggregation as $value) {
+ if (isset ($existingAggregationMapped[$value['_id']]) === true) {
$newAggregationMapped[$value['_id']] = $existingAggregationMapped[$value['_id']] + $value['count'];
} else {
$newAggregationMapped[$value['_id']] = $value['count'];
@@ -54,13 +54,13 @@ public function mergeFacets(array $existingAggregation, array $newAggregation):
private function mergeAggregations(?array $existingAggregations, ?array $newAggregations): array
{
- if($newAggregations === null) {
+ if ($newAggregations === null) {
return [];
}
- foreach($newAggregations as $key => $aggregation) {
- if(isset($existingAggregations[$key]) === false) {
+ foreach ($newAggregations as $key => $aggregation) {
+ if (isset($existingAggregations[$key]) === false) {
$existingAggregations[$key] = $aggregation;
} else {
$existingAggregations[$key] = $this->mergeFacets($existingAggregations[$key], $aggregation);
@@ -88,7 +88,7 @@ public function search(array $parameters, array $elasticConfig, array $dbConfig,
$limit = isset($parameters['.limit']) === true ? $parameters['.limit'] : 30;
$page = isset($parameters['.page']) === true ? $parameters['.page'] : 1;
- if($elasticConfig['location'] !== '') {
+ if ($elasticConfig['location'] !== '') {
$localResults = $this->elasticService->searchObject(filters: $parameters, config: $elasticConfig, totalResults: $totalResults,);
}
@@ -96,7 +96,7 @@ public function search(array $parameters, array $elasticConfig, array $dbConfig,
// $directory = $this->objectService->findObjects(filters: ['_schema' => 'directory'], config: $dbConfig);
- if(count($directory) === 0) {
+ if (count($directory) === 0) {
$pages = (int) ceil($totalResults / $limit);
return [
'results' => $localResults['results'],
@@ -116,8 +116,8 @@ public function search(array $parameters, array $elasticConfig, array $dbConfig,
$promises = [];
- foreach($directory as $instance) {
- if(
+ foreach ($directory as $instance) {
+ if (
$instance['default'] === false
|| isset($parameters['.catalogi']) === true
&& in_array($instance['catalogId'], $parameters['.catalogi']) === false
@@ -130,7 +130,7 @@ public function search(array $parameters, array $elasticConfig, array $dbConfig,
unset($parameters['.catalogi']);
- foreach($searchEndpoints as $searchEndpoint => $catalogi) {
+ foreach ($searchEndpoints as $searchEndpoint => $catalogi) {
$parameters['_catalogi'] = $catalogi;
@@ -139,8 +139,8 @@ public function search(array $parameters, array $elasticConfig, array $dbConfig,
$responses = Utils::settle($promises)->wait();
- foreach($responses as $response) {
- if($response['state'] === 'fulfilled') {
+ foreach ($responses as $response) {
+ if ($response['state'] === 'fulfilled') {
$responseData = json_decode(
json: $response['value']->getBody()->getContents(),
associative: true
@@ -323,7 +323,7 @@ public function unsetSpecialQueryParams(array $filters): array
if (str_starts_with($key, '_')) {
unset($filters[$key]);
}
- if($key === 'search') {
+ if ($key === 'search') {
unset($filters[$key]);
}
}
@@ -404,12 +404,12 @@ public function parseQueryString (string $queryString = ''): array
{
$pairs = explode(separator: '&', string: $queryString);
- foreach($pairs as $pair) {
+ foreach ($pairs as $pair) {
$kvpair = explode(separator: '=', string: $pair);
$key = urldecode(string: $kvpair[0]);
$value = '';
- if(count(value: $kvpair) === 2) {
+ if (count(value: $kvpair) === 2) {
$value = urldecode(string: $kvpair[1]);
}
diff --git a/lib/Service/ValidationService.php b/lib/Service/ValidationService.php
index 80a2035b..ff60ccaf 100644
--- a/lib/Service/ValidationService.php
+++ b/lib/Service/ValidationService.php
@@ -58,7 +58,7 @@ 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'
+ && $this->config->getValueString(app: $this->appName, key: 'mongoStorage') === '1'
) {
$filter = ['id' => $id, '_schema' => 'catalog'];
@@ -99,7 +99,7 @@ public function validatePublication(array $publication): array
}
// var_dump($catalog['metadata'], $metadata, in_array(needle: $metadata, haystack: $catalog['metadata']));
- if(in_array(needle: $metadata, haystack: $catalog['metadata']) === false) {
+ if (in_array(needle: $metadata, haystack: $catalog['metadata']) === false) {
throw new OCSBadRequestException(message: 'Given metadata object not present in catalog');
}
diff --git a/package-lock.json b/package-lock.json
index c1435f86..13151b64 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -46,6 +46,7 @@
"@nextcloud/webpack-vue-config": "^6.0.1",
"@pinia/testing": "^0.1.5",
"@types/jest": "^29.5.12",
+ "@types/lodash": "^4.17.7",
"@types/node": "^22.5.0",
"@vue/test-utils": "^2.4.6",
"@vue/vue2-jest": "^29.2.6",
@@ -4704,6 +4705,12 @@
"license": "MIT",
"peer": true
},
+ "node_modules/@types/lodash": {
+ "version": "4.17.7",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz",
+ "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==",
+ "dev": true
+ },
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -15222,8 +15229,7 @@
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "license": "MIT"
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
diff --git a/package.json b/package.json
index 9569ada9..fdccad01 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
"@nextcloud/webpack-vue-config": "^6.0.1",
"@pinia/testing": "^0.1.5",
"@types/jest": "^29.5.12",
+ "@types/lodash": "^4.17.7",
"@types/node": "^22.5.0",
"@vue/test-utils": "^2.4.6",
"@vue/vue2-jest": "^29.2.6",
diff --git a/src/dialogs/attachment/CopyAttachmentDialog.vue b/src/dialogs/attachment/CopyAttachmentDialog.vue
index 7e23f451..76a2fd1f 100644
--- a/src/dialogs/attachment/CopyAttachmentDialog.vue
+++ b/src/dialogs/attachment/CopyAttachmentDialog.vue
@@ -47,6 +47,8 @@ import { NcButton, NcDialog, NcNoteCard, NcLoadingIcon } from '@nextcloud/vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'
+import { Attachment } from '../../entities/index.js'
+
export default {
name: 'CopyAttachmentDialog',
components: {
@@ -69,62 +71,19 @@ export default {
methods: {
CopyAttachment() {
this.loading = true
- publicationStore.attachmentItem.title = 'KOPIE: ' + publicationStore.attachmentItem.title
- publicationStore.attachmentItem.status = 'concept'
- publicationStore.attachmentItem.published = 'null'
- delete publicationStore.attachmentItem.id
- delete publicationStore.attachmentItem._id
- fetch(
- '/index.php/apps/opencatalogi/api/attachments',
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(publicationStore.attachmentItem),
- },
- )
- .then((response) => {
- this.loading = false
- this.succes = true
- response.json().then((data) => {
- if (publicationStore.publicationItem) {
- publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
+ const attachmentClone = { ...publicationStore.attachmentItem }
- fetch(
- `/index.php/apps/opencatalogi/api/publications/${publicationStore.publicationItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...publicationStore.publicationItem,
- attachments: [...publicationStore.publicationItem.attachments, data.id],
- catalogi: publicationStore.publicationItem.catalogi.id,
- metaData: publicationStore.publicationItem.metaData,
- }),
- },
- )
- .then((response) => {
- this.loading = false
+ attachmentClone.title = 'KOPIE: ' + attachmentClone.title
- // Lets refresh the publicationList
- publicationStore.refreshPublicationList()
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- })
+ const newAttachmentItem = new Attachment({
+ ...attachmentClone,
+ })
- })
- .catch((err) => {
- this.error = err
- this.loading = false
- })
- // store.refreshCatalogiList()
- }
- })
- publicationStore.setAttachmentItem(response)
+ publicationStore.addAttachment(newAttachmentItem, publicationStore.publicationItem)
+ .then(({ response }) => {
+ this.loading = false
+ this.succes = response.ok
// Wait for the user to read the feedback then close the model
const self = this
diff --git a/src/dialogs/attachment/DeleteAttachmentDialog.vue b/src/dialogs/attachment/DeleteAttachmentDialog.vue
index ce93cb8b..e8959ab7 100644
--- a/src/dialogs/attachment/DeleteAttachmentDialog.vue
+++ b/src/dialogs/attachment/DeleteAttachmentDialog.vue
@@ -8,7 +8,7 @@ import { publicationStore, navigationStore } from '../../store/store.js'
name="Bijlage verwijderen"
:can-close="false">
- Wil je {{ publicationStore.attachmentItem.name ?? publicationStore.attachmentItem.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
+ Wil je {{ publicationStore.attachmentItem?.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
Bijlage succesvol verwijderd
@@ -61,7 +61,6 @@ export default {
},
data() {
return {
- filterdAttachments: [],
loading: false,
succes: false,
error: false,
@@ -70,58 +69,16 @@ export default {
methods: {
DeleteAttachment() {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/attachments/${publicationStore.attachmentItem.id}`,
- {
- method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json',
- },
- },
- )
- .then((response) => {
- this.loading = false
- this.succes = true
- // Lets refresh the attachment list
- if (publicationStore.publicationItem) {
- publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
- this.filterdAttachments = publicationStore.publicationItem.attachments.filter((attachment) => { return parseInt(attachment) !== parseInt(publicationStore.attachmentItem.id) })
-
- fetch(
- `/index.php/apps/opencatalogi/api/publications/${publicationStore.publicationItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...publicationStore.publicationItem,
- attachments: [...this.filterdAttachments],
- catalogi: publicationStore.publicationItem.catalogi.id,
- metaData: publicationStore.publicationItem.metaData,
- }),
- },
- )
- .then((response) => {
- this.loading = false
- // Lets refresh the publicationList
- publicationStore.refreshPublicationList()
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- })
- })
- .catch((err) => {
- this.error = err
- this.loading = false
- })
- }
+ publicationStore.deleteAttachment(publicationStore.attachmentItem?.id, publicationStore.publicationItem)
+ .then(({ response }) => {
+ this.loading = false
+ this.succes = response.ok
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
self.succes = false
- publicationStore.setAttachmentItem(false)
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/attachment/DepublishAttachmentDialog.vue b/src/dialogs/attachment/DepublishAttachmentDialog.vue
index 91980a76..739a2cd7 100644
--- a/src/dialogs/attachment/DepublishAttachmentDialog.vue
+++ b/src/dialogs/attachment/DepublishAttachmentDialog.vue
@@ -47,6 +47,8 @@ import { NcButton, NcDialog, NcNoteCard, NcLoadingIcon } from '@nextcloud/vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import PublishOff from 'vue-material-design-icons/PublishOff.vue'
+import { Attachment } from '../../entities/index.js'
+
export default {
name: 'DepublishAttachmentDialog',
components: {
@@ -60,7 +62,6 @@ export default {
},
data() {
return {
-
loading: false,
succes: false,
error: false,
@@ -69,32 +70,29 @@ export default {
methods: {
depublishAttachment() {
this.loading = true
- publicationStore.attachmentItem.published = null
- fetch(
- `/index.php/apps/opencatalogi/api/attachments/${publicationStore.attachmentItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(publicationStore.attachmentItem),
- },
- ).then(() => {
- this.loading = false
- this.succes = true
- if (publicationStore.publicationItem) {
- publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
- }
+ const attachmentClone = { ...publicationStore.attachmentItem }
+
+ attachmentClone.published = null
+
+ const attachmentItem = new Attachment(attachmentClone)
- // Wait for the user to read the feedback then close the model
- const self = this
- setTimeout(function() {
- self.succes = false
- publicationStore.setAttachmentItem(false)
- navigationStore.setDialog(false)
- }, 2000)
- })
+ publicationStore.editAttachment(attachmentItem)
+ .then(({ response }) => {
+ this.loading = false
+ this.succes = response.ok
+
+ if (publicationStore.publicationItem) {
+ publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
+ }
+
+ // 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
diff --git a/src/dialogs/attachment/PublishAttachmentDialog.vue b/src/dialogs/attachment/PublishAttachmentDialog.vue
index 27f37b25..2d3a1bee 100644
--- a/src/dialogs/attachment/PublishAttachmentDialog.vue
+++ b/src/dialogs/attachment/PublishAttachmentDialog.vue
@@ -5,7 +5,7 @@ import { publicationStore, navigationStore } from '../../store/store.js'
Wil je {{ publicationStore.attachmentItem.name ?? publicationStore.attachmentItem.title }} publiceren?
@@ -47,6 +47,8 @@ import { NcButton, NcDialog, NcNoteCard, NcLoadingIcon } from '@nextcloud/vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import Publish from 'vue-material-design-icons/Publish.vue'
+import { Attachment } from '../../entities/index.js'
+
export default {
name: 'PublishAttachmentDialog',
components: {
@@ -67,35 +69,31 @@ export default {
},
methods: {
PublishAttachment() {
- const now = new Date().toISOString()
this.loading = true
- publicationStore.attachmentItem.published = now
- fetch(
- `/index.php/apps/opencatalogi/api/attachments/${publicationStore.attachmentItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(publicationStore.attachmentItem),
- },
- ).then((response) => {
- this.loading = false
- this.succes = true
+ const attachmentClone = { ...publicationStore.attachmentItem }
+
+ const now = new Date().toISOString()
+ attachmentClone.published = now
+
+ const attachmentItem = new Attachment(attachmentClone)
+
+ publicationStore.editAttachment(attachmentItem)
+ .then(({ response }) => {
+ this.loading = false
+ this.succes = response.ok
- if (publicationStore.publicationItem) {
- publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
- }
+ if (publicationStore.publicationItem) {
+ publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
+ }
- // Wait for the user to read the feedback then close the model
- const self = this
- setTimeout(function() {
- self.succes = false
- publicationStore.setAttachmentItem(false)
- navigationStore.setDialog(false)
- }, 2000)
- })
+ // 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
diff --git a/src/dialogs/catalog/DeleteCatalogDialog.vue b/src/dialogs/catalog/DeleteCatalogDialog.vue
index a78eed61..0a656d27 100644
--- a/src/dialogs/catalog/DeleteCatalogDialog.vue
+++ b/src/dialogs/catalog/DeleteCatalogDialog.vue
@@ -20,7 +20,7 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
- Wil je {{ catalogiStore.catalogiItem.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
+ Wil je {{ catalogiStore.catalogiItem?.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
@@ -72,21 +72,12 @@ export default {
methods: {
DeleteCatalog() {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/catalogi/${catalogiStore.catalogiItem.id}`,
- {
- method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json',
- },
- },
- )
- .then((response) => {
+
+ catalogiStore.deleteCatalogi(catalogiStore.catalogiItem.id)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the catalogiList
- catalogiStore.refreshCatalogiList()
- catalogiStore.setCatalogiItem(false)
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
diff --git a/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue b/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue
index 593f55bc..46636f23 100644
--- a/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue
+++ b/src/dialogs/catalogiMetadata/DeleteCatalogiMetadata.vue
@@ -45,6 +45,8 @@ import { NcButton, NcDialog, NcNoteCard, NcLoadingIcon } from '@nextcloud/vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import Delete from 'vue-material-design-icons/Delete.vue'
+import { Catalogi } from '../../entities/index.js'
+
export default {
name: 'DeleteCatalogiMetadata',
components: {
@@ -58,7 +60,6 @@ export default {
},
data() {
return {
-
loading: false,
succes: false,
error: false,
@@ -69,28 +70,17 @@ export default {
const metadataArray = catalogiStore.catalogiItem?.metadata
.filter((source) => source !== metadataStore.metaDataItem?.source)
+ const CatalogiItem = new Catalogi({
+ ...catalogiStore.catalogiItem,
+ metadata: metadataArray,
+ })
+
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/catalogi/${catalogiStore.catalogiItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...catalogiStore.catalogiItem,
- metadata: metadataArray,
- }),
- },
- )
- .then((response) => {
+ catalogiStore.editCatalogi(CatalogiItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- catalogiStore.refreshCatalogiList()
- response.json().then((data) => {
- catalogiStore.setCatalogiItem(data)
- })
+ this.succes = response.ok
+
navigationStore.setSelected('catalogi')
// Wait for the user to read the feedback then close the model
const self = this
diff --git a/src/dialogs/listing/DeleteListingDialog.vue b/src/dialogs/listing/DeleteListingDialog.vue
index 5290ecbe..9e59432e 100644
--- a/src/dialogs/listing/DeleteListingDialog.vue
+++ b/src/dialogs/listing/DeleteListingDialog.vue
@@ -67,21 +67,12 @@ export default {
methods: {
DeleteCatalog() {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/directory/${directoryStore.listingItem.id}`,
- {
- method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json',
- },
- },
- )
- .then((response) => {
+
+ directoryStore.deleteListing(directoryStore.listingItem.id)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- directoryStore.refreshListingList()
- directoryStore.setListingItem(false)
+ this.succes = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
diff --git a/src/dialogs/metaData/CopyMetaDataDialog.vue b/src/dialogs/metaData/CopyMetaDataDialog.vue
index d5642fad..04e38051 100644
--- a/src/dialogs/metaData/CopyMetaDataDialog.vue
+++ b/src/dialogs/metaData/CopyMetaDataDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, metadataStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'copyMetaData'"
name="Publicatie type kopieren"
:can-close="false">
-
- Wil je {{ metadataStore.metaDataItem.title ?? metadataStore.metaDataItem.name }} kopiƫren?
+
+
+ Publicatie type succesvol gekopieerd
+
+
+ Er is iets fout gegaan bij het kopiƫren van publicatie type
+
+
+ {{ error }}
+
+
+
+ Wil je {{ metadataStore.metaDataItem.title }} kopiƫren?
-
- Publicatie type succesvol gekopieerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
@@ -44,6 +49,8 @@ import { NcButton, NcDialog, NcNoteCard, NcLoadingIcon } from '@nextcloud/vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'
+import { Metadata } from '../../entities/index.js'
+
export default {
name: 'CopyMetaDataDialog',
components: {
@@ -57,44 +64,38 @@ export default {
},
data() {
return {
-
loading: false,
- succes: false,
+ success: null,
error: false,
}
},
methods: {
CopyMetadata() {
this.loading = true
- metadataStore.metaDataItem.title = 'KOPIE: ' + metadataStore.metaDataItem.title
- if (Object.keys(metadataStore.metaDataItem.properties).length === 0) {
- delete metadataStore.metaDataItem.properties
+
+ const metadataItemClone = { ...metadataStore.metaDataItem }
+
+ metadataItemClone.title = 'KOPIE: ' + metadataItemClone.title
+ if (Object.keys(metadataItemClone.properties).length === 0) {
+ delete metadataItemClone.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) => {
+ delete metadataItemClone.id
+ delete metadataItemClone._id
+
+ const newMetadataItem = new Metadata({
+ ...metadataItemClone,
+ })
+
+ metadataStore.addMetadata(newMetadataItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- metadataStore.refreshMetaDataList()
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- })
+ this.success = response.ok
+
navigationStore.setSelected('metaData')
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/metaData/DeleteMetaDataDialog.vue b/src/dialogs/metaData/DeleteMetaDataDialog.vue
index 1f2cbb50..8b62d55e 100644
--- a/src/dialogs/metaData/DeleteMetaDataDialog.vue
+++ b/src/dialogs/metaData/DeleteMetaDataDialog.vue
@@ -6,25 +6,31 @@ import { navigationStore, metadataStore } from '../../store/store.js'
-
- Wil je {{ metadataStore.metaDataItem.title ?? metadataStore.metaDataItem.name }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
+
+
+ Publicatie type succesvol verwijderd
+
+
+ Er is iets fout gegaan bij het verwijderen van publicatie type
+
+
+ {{ error }}
+
+
+
+ Wil je {{ metadataStore.metaDataItem?.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
-
- Publicatie type succesvol verwijderd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
{
+
+ metadataStore.deleteMetadata(metadataStore.metaDataItem.id)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- metadataStore.refreshMetaDataList()
- metadataStore.setMetaDataItem(false)
+ this.success = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/metaDataProperties/CopyMetaDataPropertiesDialog.vue b/src/dialogs/metaDataProperties/CopyMetaDataPropertiesDialog.vue
index f02012c3..e3d8050d 100644
--- a/src/dialogs/metaDataProperties/CopyMetaDataPropertiesDialog.vue
+++ b/src/dialogs/metaDataProperties/CopyMetaDataPropertiesDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, metadataStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'copyMetaDataProperty'"
name="Publicatie type eigenschap verwijderen"
:can-close="false">
-
+
+
+ Publicatie type eigenschap succesvol gekopieerd
+
+
+ Er is iets fout gegaan bij het kopiƫren van publicatie type eigenschap
+
+
+ {{ error }}
+
+
+
Wil je {{ metadataStore.metadataDataKey }} kopiƫren?
-
- Publicatie type eigenschap succesvol gekopieerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
{
+ const newMetadataItem = new Metadata({
+ ...metadataItemClone,
+ })
+
+ metadataStore.editMetadata(newMetadataItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- metadataStore.refreshMetaDataList()
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- })
+ this.success = response.ok
+
navigationStore.setSelected('metaData')
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = false
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/metaDataProperties/DeleteMetaDataPropertiesDialog.vue b/src/dialogs/metaDataProperties/DeleteMetaDataPropertiesDialog.vue
index ba8ed8c8..a5ce8480 100644
--- a/src/dialogs/metaDataProperties/DeleteMetaDataPropertiesDialog.vue
+++ b/src/dialogs/metaDataProperties/DeleteMetaDataPropertiesDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, metadataStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'deleteMetaDataProperty'"
name="Publicatie type eigenschap verwijderen"
:can-close="false">
-
+
+
+ Publicatie type eigenschap succesvol verwijderd
+
+
+ Er is iets fout gegaan bij het verwijderen van publicatie type eigenschap
+
+
+ {{ error }}
+
+
+
Wil je {{ metadataStore.metadataDataKey }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
-
- Publicatie type eigenschap succesvol verwijderd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
import { NcButton, NcDialog, NcNoteCard, NcLoadingIcon } from '@nextcloud/vue'
+import { Metadata } from '../../entities/index.js'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import Delete from 'vue-material-design-icons/Delete.vue'
@@ -58,40 +64,33 @@ export default {
},
data() {
return {
-
loading: false,
- succes: false,
+ success: null,
error: false,
}
},
methods: {
DeleteProperty() {
- delete metadataStore.metaDataItem.properties[metadataStore.metadataDataKey]
-
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/metadata/${metadataStore.metaDataItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(metadataStore.metaDataItem),
- },
- )
- .then((response) => {
+
+ const metadataItemClone = { ...metadataStore.metaDataItem }
+
+ delete metadataItemClone.properties[metadataStore.metadataDataKey]
+
+ const newMetadataItem = new Metadata({
+ ...metadataItemClone,
+ })
+
+ metadataStore.editMetadata(newMetadataItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- metadataStore.refreshMetaDataList()
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- })
+ this.success = response.ok
+
navigationStore.setSelected('metaData')
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/organisation/CopyOrganisationDialog.vue b/src/dialogs/organisation/CopyOrganisationDialog.vue
index 52f23cbf..96060df7 100644
--- a/src/dialogs/organisation/CopyOrganisationDialog.vue
+++ b/src/dialogs/organisation/CopyOrganisationDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, organisationStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'copyOrganisation'"
name="Organisatie kopieren"
:can-close="false">
-
+
+
+ Organisatie succesvol gekopieerd
+
+
+ Er is iets fout gegaan bij het kopiƫren van Organisatie
+
+
+ {{ error }}
+
+
+
Wil je {{ organisationStore.organisationItem.name ?? organisationStore.organisationItem.title }} kopiƫren?
-
- Organisatie succesvol gekopieerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
@@ -43,6 +48,7 @@ import { NcButton, NcDialog, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'
+import { Organisation } from '../../entities/index.js'
export default {
name: 'CopyOrganisationDialog',
@@ -57,42 +63,33 @@ export default {
},
data() {
return {
-
loading: false,
- succes: false,
+ success: null,
error: false,
}
},
methods: {
CopyOrganisation() {
this.loading = true
- organisationStore.organisationItem.title = 'KOPIE: ' + organisationStore.organisationItem.title
- delete organisationStore.organisationItem.id
- delete organisationStore.organisationItem._id
- fetch(
- '/index.php/apps/opencatalogi/api/organisations',
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(organisationStore.organisationItem),
- },
- )
- .then((response) => {
+
+ const organisationClone = { ...organisationStore.organisationItem }
+
+ organisationClone.title = 'KOPIE: ' + organisationClone.title
+ delete organisationClone.id
+ delete organisationClone._id
+
+ const organisationItem = new Organisation(organisationClone)
+
+ organisationStore.addOrganisation(organisationItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- organisationStore.refreshOrganisationList()
- response.json().then((data) => {
- organisationStore.setOrganisationItem(data)
- })
+ this.success = response.ok
+
navigationStore.setSelected('organisations')
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
- organisationStore.setOrganisationItem(false)
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/organisation/DeleteOrganisationDialog.vue b/src/dialogs/organisation/DeleteOrganisationDialog.vue
index 674cac42..0246c511 100644
--- a/src/dialogs/organisation/DeleteOrganisationDialog.vue
+++ b/src/dialogs/organisation/DeleteOrganisationDialog.vue
@@ -7,28 +7,33 @@ import { navigationStore, organisationStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'deleteOrganisation'"
name="Organisatie verwijderen"
:can-close="false">
-
- Wil je {{ organisationStore.organisationItem.name ?? organisationStore.organisationItem.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
+
+
+ Organisatie succesvol verwijderd
+
+
+ Er is iets fout gegaan bij het verwijderen van Organisatie
+
+
+ {{ error }}
+
+
+
+ Wil je {{ organisationStore.organisationItem?.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
-
- Organisatie succesvol verwijderd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
+ @click="DeleteOrganisation()">
@@ -58,34 +63,24 @@ export default {
},
data() {
return {
-
loading: false,
- succes: false,
+ success: null,
error: false,
}
},
methods: {
- DeleteCatalog() {
+ DeleteOrganisation() {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/organisations/${organisationStore.organisationItem.id}`,
- {
- method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json',
- },
- },
- )
- .then((response) => {
+
+ organisationStore.deleteOrganisation(organisationStore.organisationItem.id)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- organisationStore.refreshOrganisationList()
- organisationStore.setOrganisationItem(false)
+ this.success = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/publication/ArchivePublicationDialog.vue b/src/dialogs/publication/ArchivePublicationDialog.vue
index c92aa39b..ac6b1e2e 100644
--- a/src/dialogs/publication/ArchivePublicationDialog.vue
+++ b/src/dialogs/publication/ArchivePublicationDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, publicationStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'archivePublication'"
name="Publicatie archiveren"
:can-close="false">
-
- Wil je {{ publicationStore.publicationItem.name ?? publicationStore.publicationItem.title }} archiveren? Dit betekend dat de publicatie wordt de gepubliceerd en niet langer vindbaar is. Bij de eerste volgende gelegenheid wordt de publicatie automatisch over gebracht naar het digitaal archief.
+
+
+ Publicatie succesvol gearchiveerd
+
+
+ Er is iets fout gegaan bij het archiveren van Publicatie
+
+
+ {{ error }}
+
+
+
+ Wil je {{ publicationStore.publicationItem?.title }} archiveren? Dit betekend dat de publicatie wordt de gepubliceerd en niet langer vindbaar is. Bij de eerste volgende gelegenheid wordt de publicatie automatisch over gebracht naar het digitaal archief.
-
- Publicatie succesvol gearchiveerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
{
+ const catalogiItem = new Publication({
+ ...publicationStore.publicationItem,
+ catalogi: publicationStore.publicationItem.catalogi.id,
+ metaData: publicationStore.publicationItem.metaData,
+ })
+
+ publicationStore.editPublication(catalogiItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- publicationStore.refreshPublicationList()
- publicationStore.getConceptPublications()
+ this.success = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
publicationStore.setPublicationItem(false)
navigationStore.setDialog(false)
}, 2000)
diff --git a/src/dialogs/publication/CopyPublicationDialog.vue b/src/dialogs/publication/CopyPublicationDialog.vue
index 72618f61..49ca3655 100644
--- a/src/dialogs/publication/CopyPublicationDialog.vue
+++ b/src/dialogs/publication/CopyPublicationDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, publicationStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'copyPublication'"
name="Publicatie kopieren"
:can-close="false">
-
- Wil je {{ publicationStore.publicationItem.name ?? publicationStore.publicationItem.title }} kopiƫren?
+
+
+ Publicatie succesvol gekopieerd
+
+
+ Er is iets fout gegaan bij het kopiƫren van Publicatie
+
+
+ {{ error }}
+
+
+
+ Wil je {{ publicationStore.publicationItem?.title }} kopiƫren?
-
- Publicatie succesvol gekopieerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
@@ -43,6 +48,7 @@ import { NcButton, NcDialog, NcNoteCard, NcLoadingIcon } from '@nextcloud/vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'
+import { Publication } from '../../entities/index.js'
export default {
name: 'CopyPublicationDialog',
@@ -57,50 +63,41 @@ export default {
},
data() {
return {
-
loading: false,
- succes: false,
+ success: null,
error: false,
}
},
methods: {
CopyPublication() {
this.loading = true
- publicationStore.publicationItem.title = 'KOPIE: ' + publicationStore.publicationItem.title
- if (Object.keys(publicationStore.publicationItem.data).length === 0) {
- delete publicationStore.publicationItem.data
+
+ const publicationClone = { ...publicationStore.publicationItem }
+
+ publicationClone.title = 'KOPIE: ' + publicationClone.title
+ if (Object.keys(publicationClone.data).length === 0) {
+ delete publicationClone.data
}
- delete publicationStore.publicationItem.id
- delete publicationStore.publicationItem._id
- publicationStore.publicationItem.status = 'concept'
- fetch(
- '/index.php/apps/opencatalogi/api/publications',
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...publicationStore.publicationItem,
- catalogi: publicationStore.publicationItem.catalogi.id,
- metaData: publicationStore.publicationItem.metaData,
- }),
- },
- )
- .then((response) => {
+ delete publicationClone.id
+ delete publicationClone._id
+ publicationClone.status = 'Concept'
+
+ const publicationItem = new Publication({
+ ...publicationClone,
+ catalogi: publicationClone.catalogi.id,
+ metaData: publicationClone.metaData,
+ })
+
+ publicationStore.addPublication(publicationItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- publicationStore.refreshPublicationList()
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- navigationStore.setSelectedCatalogus(data?.catalogi?.id)
- })
+ this.success = response.ok
+
navigationStore.setSelected('publication')
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/publication/DeletePublicationDialog.vue b/src/dialogs/publication/DeletePublicationDialog.vue
index 779483da..17473796 100644
--- a/src/dialogs/publication/DeletePublicationDialog.vue
+++ b/src/dialogs/publication/DeletePublicationDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, publicationStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'deletePublication'"
name="Publicatie verwijderen"
:can-close="false">
-
- Wil je {{ publicationStore.publicationItem.name ?? publicationStore.publicationItem.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
+
+
+ Publicatie succesvol verwijderd
+
+
+ Er is iets fout gegaan bij het verwijderen van Publicatie
+
+
+ {{ error }}
+
+
+
+ Wil je {{ publicationStore.publicationItem?.title }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
-
- Publicatie succesvol verwijderd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
{
+
+ publicationStore.deletePublication(publicationStore.publicationItem.id)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- publicationStore.refreshPublicationList()
- publicationStore.setPublicationItem(false)
+ this.success = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/dialogs/publication/DepublishPublicationDialog.vue b/src/dialogs/publication/DepublishPublicationDialog.vue
index a953648b..cabd6636 100644
--- a/src/dialogs/publication/DepublishPublicationDialog.vue
+++ b/src/dialogs/publication/DepublishPublicationDialog.vue
@@ -5,26 +5,31 @@ import { navigationStore, publicationStore } from '../../store/store.js'
-
- Wil je {{ publicationStore.publicationItem.name ?? publicationStore.publicationItem.title }} depubliceren? De publicatie is dan niet meer vindbaar via de zoek index. Bijlagen die allƩƩn aan deze publicatie zijn gekoppeld zijn dan ook niet meer vindbaar
+
+
+ Publicatie succesvol gedepubliceerd
+
+
+ Er is iets fout gegaan bij het depubliceren van Publicatie
+
+
+ {{ error }}
+
+
+
+ Wil je {{ publicationStore.publicationItem?.title }} depubliceren? De publicatie is dan niet meer vindbaar via de zoek index. Bijlagen die allƩƩn aan deze publicatie zijn gekoppeld zijn dan ook niet meer vindbaar
-
- Publicatie succesvol gedepubliceerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
{
+ const publicationClone = { ...publicationStore.publicationItem }
+
+ publicationClone.status = 'retracted'
+ publicationClone.published = ''
+
+ const publicationItem = new Publication({
+ ...publicationClone,
+ catalogi: publicationClone.catalogi.id,
+ metaData: publicationClone.metaData,
+ })
+
+ publicationStore.editPublication(publicationItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- publicationStore.refreshPublicationList()
- publicationStore.getConceptPublications()
+ this.success = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
publicationStore.setPublicationItem(false)
navigationStore.setDialog(false)
}, 2000)
diff --git a/src/dialogs/publication/DownloadPublicationDialog.vue b/src/dialogs/publication/DownloadPublicationDialog.vue
index b6b9b35d..6ec57cc5 100644
--- a/src/dialogs/publication/DownloadPublicationDialog.vue
+++ b/src/dialogs/publication/DownloadPublicationDialog.vue
@@ -7,13 +7,23 @@ import { navigationStore, publicationStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'downloadPublication'"
name="Publicatie downloaden"
:can-close="false">
-
- Hoe wilt u {{ publicationStore.publicationItem.name ?? publicationStore.publicationItem.title }} downloaden?
+
+
+ Publicatie succesvol gearchiveerd
+
+
+ Er is iets fout gegaan bij het archiveren van Publicatie
+
+
+ {{ error }}
+
+
+
+ Hoe wilt u {{ publicationStore.publicationItem?.title }} downloaden?
-
-
- Publicatie succesvol gearchiveerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
@@ -71,10 +75,7 @@ export default {
},
data() {
return {
-
- zipLoading: false,
- pdfLoading: false,
- succes: false,
+ success: null,
error: false,
}
},
@@ -82,43 +83,23 @@ export default {
downloadPublication(type) {
this.error = false
- if (type === 'pdf') { this.pdfLoading = true }
- if (type === 'zip') { this.zipLoading = true }
-
- fetch(
- `/index.php/apps/opencatalogi/api/publications/${publicationStore.publicationItem.id}/download`,
- {
- method: 'GET',
- headers: {
- Accept: `application/${type}`,
- },
- },
+ publicationStore.downloadPublication(
+ publicationStore.publicationItem.id,
+ publicationStore.publicationItem.title,
+ type,
)
+ .then(({ response, download }) => {
+ download()
+ this.success = response.ok
- .then(res => res.blob())
- .then(blob => {
- const url = window.URL.createObjectURL(new Blob([blob]))
- const link = document.createElement('a')
- link.href = url
-
- link.setAttribute('download', `${publicationStore.publicationItem.title}.${type.toLowerCase()}`)
- document.body.appendChild(link)
- link.click()
-
- this.succes = true
- this.pdfLoading = false
- this.zipLoading = false
const self = this
-
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
.catch((err) => {
this.error = err
- this.pdfLoading = false
- this.zipLoading = false
})
},
},
diff --git a/src/dialogs/publication/PublishPublicationDialog.vue b/src/dialogs/publication/PublishPublicationDialog.vue
index 62f2a444..b4cbc3d3 100644
--- a/src/dialogs/publication/PublishPublicationDialog.vue
+++ b/src/dialogs/publication/PublishPublicationDialog.vue
@@ -5,26 +5,31 @@ import { navigationStore, publicationStore } from '../../store/store.js'
-
+
+
+ Publicatie succesvol gepubliceerd
+
+
+ Er is iets fout gegaan bij het publiceren van Publicatie
+
+
+ {{ error }}
+
+
+
Wil je {{ publicationStore.publicationItem.name ?? publicationStore.publicationItem.title }} publiceren? Deze actie betekend dat de publicatie (en gepubliceerde bijlagen) worden opgenomen in de zoekindex en publiek toegankelijk zijn.
-
- Publicatie succesvol gepubliceerd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
{
+ const publicationClone = { ...publicationStore.publicationItem }
+
+ publicationClone.status = 'published'
+
+ const publicationItem = new Publication({
+ ...publicationClone,
+ catalogi: publicationClone.catalogi.id,
+ metaData: publicationClone.metaData,
+ })
+
+ publicationStore.editPublication(publicationItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- publicationStore.refreshPublicationList()
- publicationStore.getConceptPublications()
+ this.success = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = false
publicationStore.setPublicationItem(false)
navigationStore.setDialog(false)
}, 2000)
diff --git a/src/dialogs/publicationData/DeletePublicationDataDialog.vue b/src/dialogs/publicationData/DeletePublicationDataDialog.vue
index 5007bac0..8c5240c3 100644
--- a/src/dialogs/publicationData/DeletePublicationDataDialog.vue
+++ b/src/dialogs/publicationData/DeletePublicationDataDialog.vue
@@ -7,24 +7,29 @@ import { navigationStore, publicationStore } from '../../store/store.js'
v-if="navigationStore.dialog === 'deletePublicationDataDialog'"
name="Publicatie eigenschap verwijderen"
:can-close="false">
-
+
+
+ Publicatie eigenschap succesvol verwijderd
+
+
+ Er is iets fout gegaan bij het verwijderen van Publicatie eigenschap
+
+
+ {{ error }}
+
+
+
Wil je {{ publicationStore.publicationDataKey }} definitief verwijderen? Deze actie kan niet ongedaan worden gemaakt.
-
- Publicatie eigenschap succesvol verwijderd
-
-
- {{ error }}
-
- {{ succes ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
{
+
+ const publicationClone = { ...publicationStore.publicationItem }
+ delete publicationClone?.data[publicationStore.publicationDataKey]
+
+ const publicationItem = new Publication({
+ ...publicationStore.publicationItem,
+ catalogi: publicationStore.publicationItem.catalogi.id,
+ metaData: publicationStore.publicationItem.metaData,
+ })
+
+ publicationStore.editPublication(publicationItem)
+ .then(({ response }) => {
this.loading = false
- this.succes = true
- // Lets refresh the catalogiList
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- })
+ this.success = response.ok
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
- self.succes = false
+ self.success = null
navigationStore.setDialog(false)
}, 2000)
})
diff --git a/src/entities/attachment/attachment.mock.ts b/src/entities/attachment/attachment.mock.ts
index 9c19129c..060b35c3 100644
--- a/src/entities/attachment/attachment.mock.ts
+++ b/src/entities/attachment/attachment.mock.ts
@@ -2,7 +2,7 @@ import { Attachment } from './attachment'
import { TAttachment } from './attachment.types'
export const mockAttachmentsData = (): TAttachment[] => [
- { // full data
+ {
id: '1',
reference: 'ref1',
title: 'test 1',
@@ -24,6 +24,7 @@ export const mockAttachmentsData = (): TAttachment[] => [
published: new Date(2022, 9, 14).toISOString(),
modified: new Date(2022, 11, 2).toISOString(),
license: 'MIT',
+ status: 'Concept',
},
{
id: '2',
@@ -47,8 +48,9 @@ export const mockAttachmentsData = (): TAttachment[] => [
published: '',
modified: '',
license: 'MIT',
+ status: 'Concept',
},
- { // invalid data
+ {
id: '3',
reference: 'ref3',
title: 'test 3',
@@ -72,6 +74,7 @@ export const mockAttachmentsData = (): TAttachment[] => [
published: new Date(2022, 9, 14).toISOString(),
modified: new Date(2022, 11, 2).toISOString(),
license: 'MIT',
+ status: 'Concept',
},
]
diff --git a/src/entities/attachment/attachment.ts b/src/entities/attachment/attachment.ts
index 8f672b8a..3e8cbbb4 100644
--- a/src/entities/attachment/attachment.ts
+++ b/src/entities/attachment/attachment.ts
@@ -1,5 +1,8 @@
import { TAttachment } from './attachment.types'
import { SafeParseReturnType, z } from 'zod'
+import _ from 'lodash'
+
+type TStatus = 'Concept' | 'Published' | 'Withdrawn' | 'Archived' | 'revised' | 'Rejected'
export class Attachment implements TAttachment {
@@ -11,6 +14,7 @@ export class Attachment implements TAttachment {
public labels: string[]
public accessUrl: string
public downloadUrl: string
+ public status: TStatus
public type: string
public extension: string
public size: string
@@ -44,6 +48,7 @@ export class Attachment implements TAttachment {
this.labels = data.labels || []
this.accessUrl = data.accessUrl || ''
this.downloadUrl = data.downloadUrl || ''
+ this.status = _.upperFirst(data.status) as TStatus || 'Concept'
this.type = data.type || ''
this.extension = data.extension || ''
this.size = data.size || ''
@@ -68,31 +73,30 @@ export class Attachment implements TAttachment {
public validate(): SafeParseReturnType {
// https://conduction.stoplight.io/docs/open-catalogi/lsigtx7cafbr7-create-attachment
const schema = z.object({
- reference: z.string().max(255),
- title: z.string().max(255), // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
- summary: z.string().max(255),
- description: z.string().max(2555),
+ reference: z.string().max(255, 'kan niet langer dan 255 zijn'),
+ title: z.string().max(255, 'kan niet langer dan 255 zijn'), // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
+ summary: z.string().max(255, 'kan niet langer dan 255 zijn'),
+ description: z.string().max(2555, 'kan niet langer dan 2555 zijn'),
labels: z.string().array(),
- accessUrl: z.string().url().or(z.literal('')),
- downloadUrl: z.string().url().or(z.literal('')),
+ accessUrl: z.string().url('is niet een url').or(z.literal('')),
+ downloadUrl: z.string().url('is niet een url').or(z.literal('')),
+ status: z.enum(['Concept', 'Published', 'Withdrawn', 'Archived', 'Revised', 'Rejected']),
type: z.string(),
anonymization: z.object({
- anonymized: z.boolean(),
- results: z.string().max(2500),
+ anonymized: z.boolean().or(z.enum(['true', 'false'])), // because the backend turns booleans into strings for some stupid reason
+ results: z.string().max(2500, 'kan niet langer dan 2500 zijn'),
}),
language: z.object({
// this regex checks if the code has either 2 or 3 characters per group, and the -aaa after the first is optional
code: z.string()
- .max(7)
- .regex(/^([a-z]{2,3})(-[a-z]{2,3})?$/g, 'language code is not a valid ISO 639-1 code (e.g. en-us)')
+ .regex(/^([a-z]{2,3})(-[a-z]{2,3})?$/g, 'is niet een geldige ISO 639-1 code (e.g. en-us)')
.or(z.literal('')),
level: z.string()
- .max(2)
- .regex(/^(A|B|C)(1|2)$/g, 'language level is not a valid CEFRL level (e.g. A1)')
+ .regex(/^(A|B|C)(1|2)$/g, 'is niet een geldige CEFRL level (e.g. A1)')
.or(z.literal('')),
}),
versionOf: z.string(),
- published: z.string().datetime().or(z.literal('')),
+ published: z.string().datetime({ offset: true, message: 'is niet een geldige date-time' }).or(z.literal('')),
license: z.string(),
})
diff --git a/src/entities/attachment/attachment.types.ts b/src/entities/attachment/attachment.types.ts
index d43a981b..a808100e 100644
--- a/src/entities/attachment/attachment.types.ts
+++ b/src/entities/attachment/attachment.types.ts
@@ -7,6 +7,7 @@ export type TAttachment = {
labels: string[]
accessUrl: string
downloadUrl: string
+ status: 'Concept' | 'Published' | 'Withdrawn' | 'Archived' | 'revised' | 'Rejected'
type: string
extension: string
size: string
diff --git a/src/entities/catalogi/catalogi.mock.ts b/src/entities/catalogi/catalogi.mock.ts
index 7ecda8ec..62662ac9 100644
--- a/src/entities/catalogi/catalogi.mock.ts
+++ b/src/entities/catalogi/catalogi.mock.ts
@@ -9,16 +9,7 @@ export const mockCatalogiData = (): TCatalogi[] => [
description: 'a really really long description about this catalogus',
image: 'string',
listed: false,
- organisation: {
- id: '1',
- title: 'Decat',
- summary: 'a short form summary',
- description: 'a really really long description about this organisation',
- oin: 'string',
- tooi: 'string',
- rsin: 'string',
- pki: 'string',
- },
+ organisation: '2',
metadata: ['1', '3'],
},
{
@@ -28,16 +19,7 @@ export const mockCatalogiData = (): TCatalogi[] => [
description: 'a really really long description about this catalogus',
image: '',
listed: false,
- organisation: {
- id: '1',
- title: 'Decat',
- summary: 'a short form summary',
- description: 'a really really long description about this organisation',
- oin: 'string',
- tooi: 'string',
- rsin: 'string',
- pki: 'string',
- },
+ organisation: '2',
metadata: [],
},
{
diff --git a/src/entities/catalogi/catalogi.ts b/src/entities/catalogi/catalogi.ts
index 9b4e1ddc..2ae8698b 100644
--- a/src/entities/catalogi/catalogi.ts
+++ b/src/entities/catalogi/catalogi.ts
@@ -10,7 +10,7 @@ export class Catalogi implements TCatalogi {
public description: string
public image: string
public listed: boolean
- public organisation: TOrganisation
+ public organisation: string | TOrganisation // it is supposed to be TOrganisation according to the stoplight, but reality is a bit different
public metadata: string[]
@@ -34,20 +34,14 @@ export class Catalogi implements TCatalogi {
public validate(): SafeParseReturnType {
// https://conduction.stoplight.io/docs/open-catalogi/l89lv7ocvq848-create-catalog
const schema = z.object({
- title: z.string().min(1).max(255), // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
- summary: z.string().min(1).max(255),
- description: z.string().max(2555),
- image: z.string().max(255),
+ title: z.string()
+ .min(1, 'is verplicht') // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
+ .max(255, 'kan niet langer dan 255 zijn'),
+ summary: z.string().max(255, 'kan niet langer dan 255 zijn'),
+ description: z.string().max(2555, 'kan niet langer dan 2555 zijn'),
+ image: z.string().max(255, 'kan niet langer dan 255 zijn'),
listed: z.boolean(),
- organisation: z.object({
- title: z.string().min(1),
- summary: z.string().min(1),
- description: z.string(),
- oin: z.string(),
- tooi: z.string(),
- rsin: z.string(),
- pki: z.string(),
- }),
+ organisation: z.number().or(z.string()).or(z.null()),
metadata: z.string().array(),
})
diff --git a/src/entities/catalogi/catalogi.types.ts b/src/entities/catalogi/catalogi.types.ts
index 929c5e3d..2b828569 100644
--- a/src/entities/catalogi/catalogi.types.ts
+++ b/src/entities/catalogi/catalogi.types.ts
@@ -7,6 +7,6 @@ export type TCatalogi = {
description: string
image: string
listed: boolean
- organisation: TOrganisation
+ organisation: string | TOrganisation // it is supposed to be TOrganisation according to the stoplight, but reality is a bit different
metadata: string[]
}
diff --git a/src/entities/metadata/metadata.mock.ts b/src/entities/metadata/metadata.mock.ts
index fc211e30..1d7e02c5 100644
--- a/src/entities/metadata/metadata.mock.ts
+++ b/src/entities/metadata/metadata.mock.ts
@@ -15,7 +15,7 @@ export const mockMetadataData = (): TMetadata[] => [
description: 'a long description',
type: 'string',
format: 'date',
- pattern: 1,
+ pattern: '',
default: 'true',
behavior: 'silly',
required: false,
@@ -36,7 +36,7 @@ export const mockMetadataData = (): TMetadata[] => [
description: 'property description',
type: 'string',
format: 'uuid',
- pattern: 2,
+ pattern: '',
default: 'false',
behavior: 'goofy perchance',
required: false,
@@ -87,7 +87,7 @@ export const mockMetadataData = (): TMetadata[] => [
description: 'a long description',
type: 'string',
format: 'date',
- pattern: 1,
+ pattern: '',
default: 'true',
behavior: 'silly',
required: false,
@@ -108,7 +108,7 @@ export const mockMetadataData = (): TMetadata[] => [
description: 'property description',
type: 'string',
format: 'uuid',
- pattern: 2,
+ pattern: '',
default: 'false',
behavior: 'goofy perchance',
required: false,
diff --git a/src/entities/metadata/metadata.ts b/src/entities/metadata/metadata.ts
index 52bf932f..cfe0cdf4 100644
--- a/src/entities/metadata/metadata.ts
+++ b/src/entities/metadata/metadata.ts
@@ -14,7 +14,7 @@ export class Metadata implements TMetadata {
description: string
type: 'string' | 'number' | 'integer' | 'object' | 'array' | 'boolean' | 'dictionary'
format: 'date' | 'time' | 'duration' | 'date-time' | 'url' | 'uri' | 'uuid' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri-reference' | 'iri' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'regex' | 'binary' | 'byte' | 'password' | 'rsin' | 'kvk' | 'bsn' | 'oidn' | 'telephone'
- pattern: number
+ pattern: string
default: string
behavior: string
required: boolean
@@ -82,12 +82,12 @@ export class Metadata implements TMetadata {
public validate(): SafeParseReturnType {
// https://conduction.stoplight.io/docs/open-catalogi/5og7tj13bkzj5-create-metadata
const propertiesDataSchema = z.object({
- title: z.string().min(1),
+ title: z.string().min(1, 'is verplicht'),
description: z.string(),
type: z.enum(['string', 'number', 'integer', 'object', 'array', 'boolean', 'dictionary']),
format: z.enum(['date', 'time', 'duration', 'date-time', 'url', 'uri', 'uuid', 'email', 'idn-email', 'hostname', 'idn-hostname', 'ipv4', 'ipv6', 'uri-reference', 'iri', 'iri-reference', 'uri-template', 'json-pointer', 'regex', 'binary', 'byte', 'password', 'rsin', 'kvk', 'bsn', 'oidn', 'telephone'])
- .or(z.literal('')),
- pattern: z.number(),
+ .or(z.literal('')).or(z.null()), // in practice I have found this being able to be both '' and null
+ pattern: z.string(),
default: z.string(),
behavior: z.string(),
required: z.boolean(),
@@ -105,19 +105,19 @@ export class Metadata implements TMetadata {
})
const schema = z.object({
- title: z.string().min(1), // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
+ title: z.string().min(1, 'is verplicht'), // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
description: z.string(),
- summary: z.string(),
+ summary: z.string().min(1, 'is verplicht'),
version: z.string(),
required: z.string().array(),
properties: z.record(propertiesDataSchema), // z.record allows for any amount of any keys, with specific type for value validation
archive: z.object({
- valuation: z.enum(['b', 'v', 'n']),
+ valuation: z.enum(['b', 'v', 'n'], { message: "kan alleen 'b', 'v', of 'n' zijn" }),
class: z.number().refine((data: number) => {
return [1, 2, 3, 4, 5].includes(data)
- }),
+ }, 'kan alleen 1, 2, 3, 4 of 5 zijn'),
}),
- source: z.string().min(1).url(),
+ source: z.string().url('is niet een url').or(z.literal('')),
})
const result = schema.safeParse({
diff --git a/src/entities/metadata/metadata.types.ts b/src/entities/metadata/metadata.types.ts
index 05e90fe3..abe90fba 100644
--- a/src/entities/metadata/metadata.types.ts
+++ b/src/entities/metadata/metadata.types.ts
@@ -10,7 +10,7 @@ export type TMetadata = {
description: string
type: 'string' | 'number' | 'integer' | 'object' | 'array' | 'boolean' | 'dictionary'
format: 'date' | 'time' | 'duration' | 'date-time' | 'url' | 'uri' | 'uuid' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri-reference' | 'iri' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'regex' | 'binary' | 'byte' | 'password' | 'rsin' | 'kvk' | 'bsn' | 'oidn' | 'telephone'
- pattern: number
+ pattern: string
default: string
behavior: string
required: boolean
diff --git a/src/entities/organisation/organisation.mock.ts b/src/entities/organisation/organisation.mock.ts
index ecab8abd..1d17096a 100644
--- a/src/entities/organisation/organisation.mock.ts
+++ b/src/entities/organisation/organisation.mock.ts
@@ -7,27 +7,30 @@ export const mockOrganisationData = (): TOrganisation[] => [
title: 'Decat',
summary: 'a short form summary',
description: 'a really really long description about this organisation',
- oin: 'string',
- tooi: 'string',
- rsin: 'string',
- pki: 'string',
+ oin: '00000001836472635000',
+ tooi: '7843432',
+ rsin: '827342654',
+ pki: '543573424',
},
- // @ts-expect-error -- missing oin, tooi, rsin and pki properties
{
id: '2',
title: 'Woo',
summary: 'a short form summary',
description: 'a really really long description about this organisation',
+ oin: '',
+ tooi: '',
+ rsin: '',
+ pki: '',
},
{ // invalid data
id: '3',
title: '',
summary: 'a short form summary',
description: 'a really really long description about this organisation',
- oin: 'string',
- tooi: 'string',
- rsin: 'string',
- pki: 'string',
+ oin: '5435',
+ tooi: '5435',
+ rsin: '54',
+ pki: '6565',
},
]
diff --git a/src/entities/organisation/organisation.ts b/src/entities/organisation/organisation.ts
index 8017e480..d62ed9d7 100644
--- a/src/entities/organisation/organisation.ts
+++ b/src/entities/organisation/organisation.ts
@@ -32,13 +32,16 @@ export class Organisation implements TOrganisation {
public validate(): SafeParseReturnType {
// https://conduction.stoplight.io/docs/open-catalogi/ewlydzkylhygj-create-organisation
const schema = z.object({
- title: z.string().min(1),
- summary: z.string().min(1),
+ title: z.string().min(1, 'is verplicht'),
+ summary: z.string().min(1, 'is verplicht'),
description: z.string(),
- oin: z.string(),
- tooi: z.string(),
- rsin: z.string(),
- pki: z.string(),
+ // This regex could very well be faulty, as there is not any public information on HOW the OIN is made
+ // before you tell me to fix it, tell me the correct OIN format
+ // this is also true for the rest
+ oin: z.string().regex(/^0000000\d{10}000$/, 'is niet een geldige OIN nummer').or(z.literal('')),
+ tooi: z.string().regex(/^\d{1,}$/, 'is niet een geldige TOOI nummer').or(z.literal('')),
+ rsin: z.string().regex(/^\d{9}$/, 'is niet een geldige RSIN nummer').or(z.literal('')),
+ pki: z.string().regex(/^\d{1,}$/, 'is niet een geldige PKI nummer').or(z.literal('')),
})
const result = schema.safeParse({
diff --git a/src/entities/publication/publication.mock.ts b/src/entities/publication/publication.mock.ts
index fecc3efd..09476576 100644
--- a/src/entities/publication/publication.mock.ts
+++ b/src/entities/publication/publication.mock.ts
@@ -11,84 +11,11 @@ export const mockPublicationsData = (): TPublication[] => [
image: 'https://example.com/image.jpg',
category: 'category1',
portal: 'https://google.com',
- catalogi: { // full data
- id: '1',
- title: 'Decat',
- summary: 'a short form summary',
- description: 'a really really long description about this catalogus',
- image: 'string',
- listed: false,
- organisation: {
- id: '1',
- title: 'Decat',
- summary: 'a short form summary',
- description: 'a really really long description about this organisation',
- oin: 'string',
- tooi: 'string',
- rsin: 'string',
- pki: 'string',
- },
- metadata: ['1', '3'],
- },
- metaData: { // full data
- id: '1',
- title: 'Test metadata',
- description: 'this is a very long description for test metadata',
- summary: 'this is a summary',
- version: '0.0.1',
- required: ['test'],
- properties: {
- test: {
- title: 'test prop',
- description: 'a long description',
- type: 'string',
- format: 'date',
- pattern: 1,
- default: 'true',
- behavior: 'silly',
- required: false,
- deprecated: false,
- minLength: 5,
- maxLength: 6,
- example: 'gooby example',
- minimum: 1,
- maximum: 3,
- multipleOf: 1,
- exclusiveMin: false,
- exclusiveMax: false,
- minItems: 0,
- maxItems: 6,
- },
- gfdgds: {
- title: 'gfdgds prop',
- description: 'property description',
- type: 'string',
- format: 'uuid',
- pattern: 2,
- default: 'false',
- behavior: 'goofy perchance',
- required: false,
- deprecated: false,
- minLength: 5.5,
- maxLength: 5.11,
- example: 'bazinga',
- minimum: 1,
- maximum: 2,
- multipleOf: 1,
- exclusiveMin: true,
- exclusiveMax: false,
- minItems: 1,
- maxItems: 7,
- },
- },
- archive: {
- valuation: 'b',
- class: 1,
- },
- source: 'https://nextcloud.test.commonground.nu/apps/opencatalogi/api/metadata/b2f02f60-3243-49a1-82eb-75a133090e18',
- },
- published: '2024-01-01',
- modified: '2024-01-02',
+ // @ts-expect-error -- due to catalogi being get as an object and being send as a number string
+ catalogi: '2',
+ metaData: '4',
+ published: '2024-09-04T12:36:39Z',
+ modified: '2024-09-04T12:36:39Z',
featured: true,
data: {
key: 'anyvalue',
@@ -129,10 +56,11 @@ export const mockPublicationsData = (): TPublication[] => [
image: '',
category: 'category2',
portal: '',
- catalogi: '',
- metaData: '',
- published: '2024-01-01',
- modified: '2024-01-02',
+ // @ts-expect-error -- due to catalogi being get as an object and being send as a number string
+ catalogi: '2',
+ metaData: '4',
+ published: '2024-09-04T12:36:39Z',
+ modified: '2024-09-04T12:36:39Z',
featured: true,
data: {
type: '',
@@ -161,92 +89,18 @@ export const mockPublicationsData = (): TPublication[] => [
},
{ // invalid data
id: '3',
- reference: 'ref3',
title: 'test 3',
summary: 'a short form summary',
description: 'a really really long description about this catalogus',
- image: 'https://example.com/image.jpg',
+ reference: 'ref3',
+ image: '',
category: 'category3',
- portal: 'https://google.com',
- catalogi: { // full data
- id: '3',
- title: 'Foo',
- summary: 'a short form summary',
- description: 'a really really long description about this catalogus',
- image: 'string',
- // @ts-expect-error -- listed needs to be a boolean
- listed: 0.2,
- organisation: {
- id: '1',
- title: 'Decat',
- summary: 'a short form summary',
- description: 'a really really long description about this organisation',
- oin: 'string',
- tooi: 'string',
- rsin: 'string',
- pki: 'string',
- },
- metadata: ['1', '3'],
- },
- metaData: { // full data
- id: '1',
- title: 'Test metadata',
- description: 'this is a very long description for test metadata',
- summary: 'this is a summary',
- version: '0.0.1',
- required: ['test'],
- properties: {
- test: {
- title: 'test prop',
- description: 'a long description',
- type: 'string',
- format: 'date',
- pattern: 1,
- default: 'true',
- behavior: 'silly',
- required: false,
- deprecated: false,
- minLength: 5,
- maxLength: 6,
- example: 'gooby example',
- minimum: 1,
- maximum: 3,
- multipleOf: 1,
- exclusiveMin: false,
- exclusiveMax: false,
- minItems: 0,
- maxItems: 6,
- },
- gfdgds: {
- title: 'gfdgds prop',
- description: 'property description',
- type: 'string',
- format: 'uuid',
- pattern: 2,
- default: 'false',
- behavior: 'goofy perchance',
- required: false,
- deprecated: false,
- minLength: 5.5,
- maxLength: 5.11,
- example: 'bazinga',
- minimum: 1,
- maximum: 2,
- multipleOf: 1,
- exclusiveMin: true,
- exclusiveMax: false,
- minItems: 1,
- maxItems: 7,
- },
- },
- archive: {
- valuation: 'b',
- class: 1,
- },
- source: 'https://nextcloud.test.commonground.nu/apps/opencatalogi/api/metadata/b2f02f60-3243-49a1-82eb-75a133090e18',
- },
- published: '2024-01-01',
- modified: '2024-01-02',
+ portal: '',
+ // @ts-expect-error -- expected wrong type
+ catalogi: 3,
+ metaData: '3',
+ published: '2024-09-04T12:36:39Z',
+ modified: '2024-09-04T12:36:39Z',
featured: true,
data: {
type: '',
diff --git a/src/entities/publication/publication.ts b/src/entities/publication/publication.ts
index cbe326ee..b1a9edbb 100644
--- a/src/entities/publication/publication.ts
+++ b/src/entities/publication/publication.ts
@@ -1,6 +1,9 @@
-import { TAttachment, TCatalogi, TMetadata } from '../'
+import { TCatalogi, TMetadata } from '../'
import { TPublication } from './publication.types'
import { SafeParseReturnType, z } from 'zod'
+import _ from 'lodash'
+
+type TStatus = 'Concept' | 'Published' | 'Withdrawn' | 'Archived' | 'revised' | 'Rejected'
export class Publication implements TPublication {
@@ -14,8 +17,8 @@ export class Publication implements TPublication {
public portal: string
public featured: boolean
public schema: string
- public status: 'Concept' | 'Published' | 'Withdrawn' | 'Archived' | 'revised' | 'Rejected'
- public attachments: TAttachment[]
+ public status: TStatus
+ public attachments: number[]
public attachmentCount: number
public themes: string[]
public data: Record
@@ -42,7 +45,7 @@ export class Publication implements TPublication {
coordinates: [number, number]
}
- public catalogi: string | TCatalogi
+ public catalogi: TCatalogi
public metaData: string | TMetadata
constructor(data: TPublication) {
@@ -65,7 +68,7 @@ export class Publication implements TPublication {
|| (typeof data.featured === 'string' && !!parseInt(data.featured))
|| false
this.schema = data.schema || ''
- this.status = data.status || 'Concept'
+ this.status = _.upperFirst(data.status) as TStatus || 'Concept'
this.attachments = data.attachments || []
this.attachmentCount = this.attachmentCount || data.attachments?.length || 0
this.themes = data.themes || []
@@ -93,7 +96,8 @@ export class Publication implements TPublication {
coordinates: [0, 0],
}
- this.catalogi = data.catalogi || ''
+ // @ts-expect-error -- im not gonna bother rewriting the catalogi structure here
+ this.catalogi = data.catalogi || {}
// @ts-expect-error -- for backwards compatibility metadata will be used if metaData cannot be found
this.metaData = (data.metaData ?? data.metadata) || ''
}
@@ -102,43 +106,45 @@ export class Publication implements TPublication {
public validate(): SafeParseReturnType {
// https://conduction.stoplight.io/docs/open-catalogi/jcrqsdtnjtx8v-create-publication
const schema = z.object({
- title: z.string().min(1), // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
- summary: z.string().min(1),
+ title: z.string().min(1, 'is verplicht'), // .min(1) on a string functionally works the same as a nonEmpty check (SHOULD NOT BE COMBINED WITH .OPTIONAL())
+ summary: z.string().min(1, 'is verplicht'),
description: z.string(),
reference: z.string(),
- image: z.string().url().or(z.literal('')), // its either a URL or empty
+ image: z.string().url('is niet een url').or(z.literal('')), // its either a URL or empty
category: z.string(),
- portal: z.string().url().or(z.literal('')),
+ portal: z.string().url('is niet een url').or(z.literal('')),
featured: z.boolean(),
- schema: z.string().url().min(1),
+ schema: z.string().min(1, 'is verplicht').url('is niet een url'),
status: z.enum(['Concept', 'Published', 'Withdrawn', 'Archived', 'Revised', 'Rejected']),
- // FIXME z.object({}) here is dangerous since it will strip everything out of attachments if data is parsed
- // It will not cause an issue for validation only
- attachments: z.object({}).array(),
+ attachments: z.union([z.string(), z.number()]).array(),
attachmentCount: z.number(),
themes: z.string().array(),
data: z.record(z.string(), z.any()),
anonymization: z.object({
anonymized: z.boolean(),
- results: z.string().max(2500),
+ results: z.string().max(2500, 'kan niet langer dan 2500 zijn'),
}),
language: z.object({
// this regex checks if the code has either 2 or 3 characters per group, and the -aaa after the first is optional
code: z.string()
- .max(7)
- .regex(/([a-z]{2,3})(-[a-z]{2,3})?/g, 'language code is not a valid ISO 639-1 code (e.g. en-us)'),
- level: z.string().min(1),
+ .regex(/^([a-z]{2,3})(-[a-z]{2,3})?$/g, 'is niet een geldige ISO 639-1 code (e.g. en-us)')
+ .or(z.literal('')),
+ level: z.string()
+ .regex(/^(A|B|C)(1|2)$/g, 'is niet een geldige CEFRL level (e.g. A1)')
+ .or(z.literal('')),
}),
- published: z.string(),
- modified: z.string(),
+ published: z.string().datetime({ offset: true }).or(z.literal('')),
+ modified: z.string().datetime({ offset: true }).or(z.literal('')),
license: z.string(),
archive: z.object({
date: z.string().datetime().or(z.literal('')),
}),
geo: z.object({
type: z.enum(['Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString', 'MultiPolygon']),
- coordinates: z.number().array().min(2).max(2),
+ coordinates: z.tuple([z.number(), z.number()]),
}),
+ catalogi: z.string().or(z.number()),
+ metaData: z.string(), // this is not specified within the stoplight
})
const result = schema.safeParse({
diff --git a/src/entities/publication/publication.types.ts b/src/entities/publication/publication.types.ts
index 592169f9..2c3a4f65 100644
--- a/src/entities/publication/publication.types.ts
+++ b/src/entities/publication/publication.types.ts
@@ -1,6 +1,6 @@
// TODO: double check this type for correct properties and optionals when stoplight updates - https://conduction.stoplight.io/docs/open-catalogi/fee989a9c8e3f-publication
-import { TAttachment, TCatalogi, TMetadata } from '../'
+import { TCatalogi, TMetadata } from '../'
export type TPublication = {
id: string
@@ -14,7 +14,7 @@ export type TPublication = {
featured: boolean
schema: string
status: 'Concept' | 'Published' | 'Withdrawn' | 'Archived' | 'revised' | 'Rejected'
- attachments: TAttachment[]
+ attachments: number[]
attachmentCount: number
themes: string[]
data: Record
@@ -36,6 +36,6 @@ export type TPublication = {
type: 'Point' | 'LineString' | 'Polygon' | 'MultiPoint' | 'MultiLineString' | 'MultiPolygon'
coordinates: [number, number]
}
- catalogi: string | TCatalogi
+ catalogi: TCatalogi
metaData: string | TMetadata
}
diff --git a/src/entities/theme/theme.ts b/src/entities/theme/theme.ts
index 8e24759e..3adcea21 100644
--- a/src/entities/theme/theme.ts
+++ b/src/entities/theme/theme.ts
@@ -26,8 +26,8 @@ export class Theme implements TTheme {
public validate(): SafeParseReturnType {
// https://conduction.stoplight.io/docs/open-catalogi/hpksgr0u1cwj8-theme
const schema = z.object({
- title: z.string().min(1),
- summary: z.string().min(1),
+ title: z.string().min(1, 'is verplicht'),
+ summary: z.string().min(1, 'is verplicht'),
description: z.string(),
image: z.string(),
})
diff --git a/src/main.js b/src/main.js
index 11977c19..b460c5d8 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) // it would be nice if this was in the documentation.. NEXT CLOUD!!!
new Vue(
{
diff --git a/src/modals/attachment/AddAttachmentModal.vue b/src/modals/attachment/AddAttachmentModal.vue
index 9e519d0a..d84de539 100644
--- a/src/modals/attachment/AddAttachmentModal.vue
+++ b/src/modals/attachment/AddAttachmentModal.vue
@@ -26,25 +26,34 @@ import { navigationStore, publicationStore } from '../../store/store.js'
label="Titel"
maxlength="255"
:value.sync="publicationStore.attachmentItem.title"
- required />
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.accessUrl"
+ :error="!!inputValidation.fieldErrors?.['accessUrl']"
+ :helper-text="inputValidation.fieldErrors?.['accessUrl']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.downloadUrl"
+ :error="!!inputValidation.fieldErrors?.['downloadUrl']"
+ :helper-text="inputValidation.fieldErrors?.['downloadUrl']?.[0]" />
@@ -84,7 +93,8 @@ import { navigationStore, publicationStore } from '../../store/store.js'
@@ -110,6 +120,8 @@ import TrayArrowDown from 'vue-material-design-icons/TrayArrowDown.vue'
import axios from 'axios'
+import { Publication, Attachment } from '../../entities/index.js'
+
const dropZoneRef = ref()
const { openFileUpload, files, reset, setFiles } = useFileSelection({ allowMultiple: false, dropzone: dropZoneRef })
@@ -143,6 +155,21 @@ export default {
},
}
},
+ computed: {
+ inputValidation() {
+ const catalogiItem = new Attachment({
+ ...publicationStore.attachmentItem,
+ })
+
+ const result = catalogiItem.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
watch: {
dropFiles: {
handler(addedFiles) {
@@ -187,30 +214,16 @@ export default {
if (publicationStore.publicationItem) {
publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
- fetch(
- `/index.php/apps/opencatalogi/api/publications/${publicationStore.publicationItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...publicationStore.publicationItem,
- attachments: [...publicationStore.publicationItem.attachments, response.data.id],
- catalogi: publicationStore.publicationItem.catalogi.id,
- metaData: publicationStore.publicationItem.metaData,
- }),
- },
- )
- .then((response) => {
- this.loading = false
-
- // Lets refresh the publicationList
- publicationStore.refreshPublicationList()
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- })
+ const newPublicationItem = new Publication({
+ ...publicationStore.publicationItem,
+ attachments: [...publicationStore.publicationItem.attachments, response.data.id],
+ catalogi: publicationStore.publicationItem.catalogi.id,
+ metaData: publicationStore.publicationItem.metaData,
+ })
+ publicationStore.editPublication(newPublicationItem)
+ .then(() => {
+ this.loading = false
})
.catch((err) => {
this.error = err
diff --git a/src/modals/attachment/EditAttachmentModal.vue b/src/modals/attachment/EditAttachmentModal.vue
index 5c47e596..051b114a 100644
--- a/src/modals/attachment/EditAttachmentModal.vue
+++ b/src/modals/attachment/EditAttachmentModal.vue
@@ -25,28 +25,38 @@ import { navigationStore, publicationStore } from '../../store/store.js'
label="Titel"
maxlength="255"
:value.sync="publicationStore.attachmentItem.title"
- required />
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.accessUrl"
+ :error="!!inputValidation.fieldErrors?.['accessUrl']"
+ :helper-text="inputValidation.fieldErrors?.['accessUrl']?.[0]" />
+ :value.sync="publicationStore.attachmentItem.downloadUrl"
+ :error="!!inputValidation.fieldErrors?.['downloadUrl']"
+ :helper-text="inputValidation.fieldErrors?.['downloadUrl']?.[0]" />
@@ -64,6 +74,8 @@ import { navigationStore, publicationStore } from '../../store/store.js'
import { NcButton, NcModal, NcTextField, NcTextArea, NcNoteCard, NcLoadingIcon, NcSelect } from '@nextcloud/vue'
import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue'
+import { Attachment } from '../../entities/index.js'
+
export default {
name: 'EditAttachmentModal',
components: {
@@ -90,34 +102,39 @@ export default {
},
}
},
+ computed: {
+ inputValidation() {
+ const catalogiItem = new Attachment({
+ ...publicationStore.attachmentItem,
+ })
+
+ const result = catalogiItem.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
methods: {
editAttachment() {
this.loading = true
this.error = false
- fetch(
- `/index.php/apps/opencatalogi/api/attachments/${publicationStore.attachmentItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...publicationStore.attachmentItem,
- published: publicationStore.attachmentItem.published === '' ? null : publicationStore.attachmentItem.published,
- }),
- },
- )
- .then((response) => {
+ const newAttachmentItem = new Attachment({
+ ...publicationStore.attachmentItem,
+ published: publicationStore.attachmentItem.published === '' ? null : publicationStore.attachmentItem.published,
+ })
+
+ publicationStore.editAttachment(newAttachmentItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
// Lets refresh the catalogiList
if (publicationStore.publicationItem) {
publicationStore.getPublicationAttachments(publicationStore.publicationItem?.id)
}
- response.json().then((data) => {
- publicationStore.setAttachmentItem(data)
- })
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
diff --git a/src/modals/catalog/AddCatalogModal.vue b/src/modals/catalog/AddCatalogModal.vue
index 5ff12088..c657a057 100644
--- a/src/modals/catalog/AddCatalogModal.vue
+++ b/src/modals/catalog/AddCatalogModal.vue
@@ -1,5 +1,5 @@
@@ -24,15 +24,21 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
+ :value.sync="catalogi.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="catalogi.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="catalogi.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
@@ -45,7 +51,8 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
:disabled="loading" />
@@ -63,6 +70,8 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
import { NcButton, NcModal, NcTextField, NcLoadingIcon, NcNoteCard, NcCheckboxRadioSwitch, NcSelect } from '@nextcloud/vue'
import Plus from 'vue-material-design-icons/Plus.vue'
+import { Catalogi } from '../../entities/index.js'
+
export default {
name: 'AddCatalogModal',
components: {
@@ -93,6 +102,22 @@ export default {
hasUpdated: false,
}
},
+ computed: {
+ inputValidation() {
+ const catalogiItem = new Catalogi({
+ ...this.catalogi,
+ organisation: this.organisations.value?.id,
+ })
+
+ const result = catalogiItem.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
updated() {
if (navigationStore.modal === 'addCatalog' && !this.hasUpdated) {
this.fetchOrganisations()
@@ -102,6 +127,7 @@ export default {
methods: {
closeModal() {
navigationStore.setModal(false)
+ self.hasUpdated = false
this.catalogi = {
title: '',
summary: '',
@@ -111,18 +137,17 @@ export default {
},
fetchOrganisations() {
this.organisationsLoading = true
- fetch('/index.php/apps/opencatalogi/api/organisations', {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
- this.organisations = {
- options: data.results.map((organisation) => ({
- id: organisation.id,
- label: organisation.title,
- })),
- }
- })
+
+ organisationStore.getAllOrganisation()
+ .then(({ response, data }) => {
+
+ this.organisations = {
+ options: data.map((organisation) => ({
+ id: organisation.id,
+ label: organisation.title,
+ })),
+ }
+
this.organisationsLoading = false
})
.catch((err) => {
@@ -133,32 +158,21 @@ export default {
addCatalog() {
this.loading = true
this.error = false
- fetch(
- '/index.php/apps/opencatalogi/api/catalogi',
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...this.catalogi,
- organisation: this.organisations.value?.id,
- }),
- },
- )
- .then((response) => {
+
+ const CatalogiItem = new Catalogi({
+ ...this.catalogi,
+ organisation: this.organisations.value?.id,
+ })
+
+ catalogiStore.addCatalogi(CatalogiItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the catalogiList
- catalogiStore.refreshCatalogiList()
- response.json().then((data) => {
- catalogiStore.setCatalogiItem(data)
- })
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
self.success = null
- self.hasUpdated = false
self.closeModal()
}, 2000)
})
diff --git a/src/modals/catalog/EditCatalogModal.vue b/src/modals/catalog/EditCatalogModal.vue
index 6dffc327..f810c47d 100644
--- a/src/modals/catalog/EditCatalogModal.vue
+++ b/src/modals/catalog/EditCatalogModal.vue
@@ -1,5 +1,5 @@
@@ -24,19 +24,24 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
+ :value.sync="catalogiItem.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="catalogiItem.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="catalogiItem.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
+ :checked.sync="catalogiItem.listed">
Publiek vindbaar
@@ -64,6 +70,8 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
import { NcButton, NcModal, NcTextField, NcNoteCard, NcLoadingIcon, NcCheckboxRadioSwitch, NcSelect } from '@nextcloud/vue'
import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue'
+import { Catalogi } from '../../entities/index.js'
+
export default {
name: 'EditCatalogModal',
components: {
@@ -95,6 +103,22 @@ export default {
hasUpdated: false,
}
},
+ computed: {
+ inputValidation() {
+ const catalogiItem = new Catalogi({
+ ...this.catalogiItem,
+ organisation: this.organisations.value?.id,
+ })
+
+ const result = catalogiItem.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
mounted() {
// catalogiStore.catalogiItem can be false, so only assign catalogiStore.catalogiItem to catalogiItem if its NOT false
catalogiStore.catalogiItem && (this.catalogiItem = catalogiStore.catalogiItem)
@@ -117,17 +141,10 @@ export default {
},
fetchData(id) {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/catalogi/${id}`,
- {
- method: 'GET',
- },
- )
- .then((response) => {
- response.json().then((data) => {
- catalogiStore.setCatalogiItem(data)
- this.catalogiItem = catalogiStore.catalogiItem
- })
+
+ catalogiStore.getOneCatalogi(id)
+ .then(({ response, data }) => {
+ this.catalogiItem = data
this.loading = false
})
.catch((err) => {
@@ -137,26 +154,24 @@ export default {
},
fetchOrganisations() {
this.organisationsLoading = true
- fetch('/index.php/apps/opencatalogi/api/organisations', {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
- const selectedOrganisation = data.results.filter((org) => org?.id.toString() === catalogiStore.catalogiItem?.organisation.toString())[0] || null
-
- this.organisations = {
- options: data.results.map((organisation) => ({
- id: organisation.id,
- label: organisation.title,
- })),
- value: selectedOrganisation
- ? {
- id: selectedOrganisation?.id,
- label: selectedOrganisation?.title,
- }
- : null,
- }
- })
+
+ organisationStore.getAllOrganisation()
+ .then(({ response, data }) => {
+ const selectedOrganisation = data.filter((org) => org?.id.toString() === catalogiStore.catalogiItem?.organisation.toString())[0] || null
+
+ this.organisations = {
+ options: data.map((organisation) => ({
+ id: organisation.id,
+ label: organisation.title,
+ })),
+ value: selectedOrganisation
+ ? {
+ id: selectedOrganisation?.id,
+ label: selectedOrganisation?.title,
+ }
+ : null,
+ }
+
this.organisationsLoading = false
})
.catch((err) => {
@@ -167,27 +182,17 @@ export default {
editCatalog() {
this.loading = true
this.error = false
- fetch(
- `/index.php/apps/opencatalogi/api/catalogi/${catalogiStore.catalogiItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...catalogiStore.catalogiItem,
- organisation: this.organisations?.value?.id,
- }),
- },
- )
- .then((response) => {
+
+ const CatalogiItem = new Catalogi({
+ ...this.catalogiItem,
+ organisation: this.organisations.value?.id,
+ })
+
+ catalogiStore.editCatalogi(CatalogiItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the catalogiList
- catalogiStore.refreshCatalogiList()
- response.json().then((data) => {
- catalogiStore.setCatalogiItem(data)
- })
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
diff --git a/src/modals/catalogiMetadata/AddCatalogiMetadata.vue b/src/modals/catalogiMetadata/AddCatalogiMetadata.vue
index fcd1b5e9..d37732bb 100644
--- a/src/modals/catalogiMetadata/AddCatalogiMetadata.vue
+++ b/src/modals/catalogiMetadata/AddCatalogiMetadata.vue
@@ -1,5 +1,5 @@
@@ -45,6 +45,8 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
import { NcButton, NcModal, NcLoadingIcon, NcNoteCard, NcSelect } from '@nextcloud/vue'
import Plus from 'vue-material-design-icons/Plus.vue'
+import { Catalogi } from '../../entities/index.js'
+
export default {
name: 'AddCatalogiMetadata',
components: {
@@ -101,17 +103,11 @@ export default {
},
fetchData(id) {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/catalogi/${id}`,
- {
- method: 'GET',
- },
- )
- .then((response) => {
- response.json().then((data) => {
- catalogiStore.setCatalogiItem(data)
- this.catalogiItem = catalogiStore.catalogiItem
- })
+
+ catalogiStore.getOneCatalogi(id)
+ .then(({ response, data }) => {
+ this.catalogiItem = catalogiStore.catalogiItem
+
this.loading = false
})
.catch((err) => {
@@ -121,21 +117,19 @@ export default {
},
fetchMetaData(metadataList) {
this.metaDataLoading = true
- fetch('/index.php/apps/opencatalogi/api/metadata', {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
-
- const filteredData = data.results.filter((meta) => !metadataList.includes(meta?.source))
-
- this.metaData = {
- options: filteredData.map((metaData) => ({
- source: metaData.source,
- label: metaData.title,
- })),
- }
- })
+
+ metadataStore.getAllMetadata()
+ .then(({ response, data }) => {
+
+ const filteredData = data.filter((meta) => !metadataList.includes(meta?.source))
+
+ this.metaData = {
+ options: filteredData.map((metaData) => ({
+ source: metaData.source,
+ label: metaData.title,
+ })),
+ }
+
this.metaDataLoading = false
})
.catch((err) => {
@@ -155,27 +149,16 @@ export default {
return
}
- fetch(
- `/index.php/apps/opencatalogi/api/catalogi/${this.catalogiItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...this.catalogiItem,
- metadata: this.catalogiItem.metadata,
- }),
- },
- )
- .then((response) => {
+ const newCatalogiItem = new Catalogi({
+ ...this.catalogiItem,
+ metadata: this.catalogiItem.metadata,
+ })
+
+ catalogiStore.editCatalogi(newCatalogiItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the catalogiList
- catalogiStore.refreshCatalogiList()
- response.json().then((data) => {
- catalogiStore.setCatalogiItem(data)
- })
+
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
diff --git a/src/modals/directory/AddDirectoryModal.vue b/src/modals/directory/AddDirectoryModal.vue
index 4755e4e1..b0066299 100644
--- a/src/modals/directory/AddDirectoryModal.vue
+++ b/src/modals/directory/AddDirectoryModal.vue
@@ -76,7 +76,9 @@ export default {
methods: {
addDirectory() {
this.loading = true
+
this.$emit('metadata', this.title)
+
fetch('/index.php/apps/opencatalogi/api/directory', {
method: 'POST',
headers: {
diff --git a/src/modals/metaData/AddMetaDataModal.vue b/src/modals/metaData/AddMetaDataModal.vue
index 9a15ba66..8be5d844 100644
--- a/src/modals/metaData/AddMetaDataModal.vue
+++ b/src/modals/metaData/AddMetaDataModal.vue
@@ -23,22 +23,29 @@ import { navigationStore, metadataStore } from '../../store/store.js'
+ :value.sync="metadata.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="metadata.version"
+ :error="!!inputValidation.fieldErrors?.['version']"
+ :helper-text="inputValidation.fieldErrors?.['version']?.[0]" />
+ :value.sync="metadata.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="metadata.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
@@ -55,6 +62,8 @@ import { navigationStore, metadataStore } from '../../store/store.js'
import { NcButton, NcModal, NcTextField, NcTextArea, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'
import Plus from 'vue-material-design-icons/Plus.vue'
+import { Metadata } from '../../entities/index.js'
+
export default {
name: 'AddMetaDataModal',
components: {
@@ -69,8 +78,7 @@ export default {
},
data() {
return {
-
- metaData: {
+ metadata: {
title: '',
version: '',
description: '',
@@ -82,10 +90,25 @@ export default {
error: false,
}
},
+ computed: {
+ inputValidation() {
+ const metadataItem = new Metadata({
+ ...this.metadata,
+ })
+
+ const result = metadataItem.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
methods: {
closeModal() {
this.success = null
- this.metaData = {
+ this.metadata = {
title: '',
version: '',
description: '',
@@ -97,32 +120,16 @@ export default {
addMetaData() {
this.loading = true
- // Prevent setting source on any way.
- if (this.metadata?.source !== undefined) {
- delete this.metadata.source
- }
+ const metadataItem = new Metadata({
+ ...this.metadata,
+ })
- fetch(
- '/index.php/apps/opencatalogi/api/metadata',
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...this.metaData,
- }),
- },
- )
- .then((response) => {
+ metadataStore.addMetadata(metadataItem)
+ .then(({ response }) => {
// Set the form
this.loading = false
this.success = response.ok
- // Lets refresh the catalogiList
- metadataStore.refreshMetaDataList()
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- })
+
navigationStore.setSelected('metaData')
// Update the list
const self = this
diff --git a/src/modals/metaData/AddMetaDataPropertyModal.vue b/src/modals/metaData/AddMetaDataPropertyModal.vue
index 9bd083e0..c3aad9bb 100644
--- a/src/modals/metaData/AddMetaDataPropertyModal.vue
+++ b/src/modals/metaData/AddMetaDataPropertyModal.vue
@@ -274,6 +274,8 @@ import {
// icons
import Plus from 'vue-material-design-icons/Plus.vue'
+import { Metadata } from '../../entities/index.js'
+
export default {
name: 'AddMetaDataPropertyModal',
components: {
@@ -347,39 +349,29 @@ export default {
methods: {
addMetadata() {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/metadata/${metadataStore.metaDataItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
+
+ const newMetadataItem = new Metadata({
+ ...metadataStore.metaDataItem,
+ properties: { // due to bad (no) support for number fields inside nextcloud/vue, parse the text to a number
+ ...metadataStore.metaDataItem.properties,
+ [this.properties.name]: {
+ ...this.properties,
+ minLength: parseFloat(this.properties.minLength) || null,
+ maxLength: parseFloat(this.properties.maxLength) || null,
+ minimum: parseFloat(this.properties.minimum) || null,
+ maximum: parseFloat(this.properties.maximum) || null,
+ multipleOf: parseFloat(this.properties.multipleOf) || null,
+ minItems: parseFloat(this.properties.minItems) || null,
+ maxItems: parseFloat(this.properties.maxItems) || null,
},
- body: JSON.stringify({
- ...metadataStore.metaDataItem,
- properties: { // due to bad (no) support for number fields inside nextcloud/vue, parse the text to a number
- ...metadataStore.metaDataItem.properties,
- [this.properties.name]: {
- ...this.properties,
- minLength: parseFloat(this.properties.minLength) || null,
- maxLength: parseFloat(this.properties.maxLength) || null,
- minimum: parseFloat(this.properties.minimum) || null,
- maximum: parseFloat(this.properties.maximum) || null,
- multipleOf: parseFloat(this.properties.multipleOf) || null,
- minItems: parseFloat(this.properties.minItems) || null,
- maxItems: parseFloat(this.properties.maxItems) || null,
- },
- },
- }),
},
- )
- .then((response) => {
+ })
+
+ metadataStore.editMetadata(newMetadataItem)
+ .then(({ response }) => {
this.loading = false
- this.success = true
- // Lets refresh the catalogiList
- metadataStore.refreshMetaDataList()
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- })
+ this.success = response.ok
+
setTimeout(() => {
// lets reset
this.properties = {
diff --git a/src/modals/metaData/EditMetaDataModal.vue b/src/modals/metaData/EditMetaDataModal.vue
index 69295d6a..8a4b3e0b 100644
--- a/src/modals/metaData/EditMetaDataModal.vue
+++ b/src/modals/metaData/EditMetaDataModal.vue
@@ -24,24 +24,31 @@ import { navigationStore, metadataStore } from '../../store/store.js'
+ :value.sync="metadata.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="metadata.version"
+ :error="!!inputValidation.fieldErrors?.['version']"
+ :helper-text="inputValidation.fieldErrors?.['version']?.[0]" />
+ :value.sync="metadata.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="metadata.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
-
@@ -58,6 +65,8 @@ import { navigationStore, metadataStore } from '../../store/store.js'
import { NcButton, NcModal, NcTextField, NcTextArea, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'
import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue'
+import { Metadata } from '../../entities/index.js'
+
export default {
name: 'EditMetaDataModal',
components: {
@@ -72,26 +81,54 @@ export default {
},
data() {
return {
+ metadata: {
+ title: '',
+ version: '',
+ summary: '',
+ description: '',
+ },
loading: false,
success: null,
error: false,
- metadataRequired: '',
+ hasUpdated: false,
+ }
+ },
+ computed: {
+ inputValidation() {
+ const metadataItem = new Metadata({
+ ...this.metadata,
+ })
+
+ const result = metadataItem.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
+ mounted() {
+ // metadataStore.metadataItem can be false, so only assign metadataStore.metadataItem to metadata if its NOT false
+ metadataStore.metaDataItem && (this.metadata = metadataStore.metaDataItem)
+ },
+ updated() {
+ if (navigationStore.modal === 'editMetaData' && this.hasUpdated) {
+ if (this.metadata.id === metadataStore.metaDataItem.id) return
+ this.hasUpdated = false
+ }
+ if (navigationStore.modal === 'editMetaData' && !this.hasUpdated) {
+ metadataStore.metaDataItem && (this.metadata = metadataStore.metaDataItem)
+ this.fetchData(metadataStore.metaDataItem.id)
+ this.hasUpdated = true
}
},
methods: {
fetchData(id) {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/metadata/${id}`,
- {
- method: 'GET',
- },
- )
- .then((response) => {
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- this.metadataRequired = data.required.toString()
- })
+
+ metadataStore.getOneMetadata(id)
+ .then(() => {
this.loading = false
})
.catch((err) => {
@@ -102,37 +139,26 @@ export default {
editMetaData() {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/metadata/${metadataStore.metaDataItem?.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...metadataStore.metaDataItem,
- required: this.metadataRequired.split(/, */g),
- }),
- },
- ).then((response) => {
- this.loading = false
- this.success = response.ok
- // 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.success = null
- navigationStore.setModal(false)
- }, 2000)
- }).catch((err) => {
- this.error = err
- this.loading = false
+ const metadataItem = new Metadata({
+ ...this.metadata,
})
+
+ metadataStore.editMetadata(metadataItem)
+ .then(({ response }) => {
+ this.loading = false
+ this.success = response.ok
+
+ navigationStore.setSelected('metaData')
+ // Wait for the user to read the feedback then close the model
+ const self = this
+ setTimeout(function() {
+ self.success = null
+ navigationStore.setModal(false)
+ }, 2000)
+ }).catch((err) => {
+ this.error = err
+ this.loading = false
+ })
},
},
}
diff --git a/src/modals/metaData/EditMetaDataPropertyModal.vue b/src/modals/metaData/EditMetaDataPropertyModal.vue
index 754b48ed..f551c7fb 100644
--- a/src/modals/metaData/EditMetaDataPropertyModal.vue
+++ b/src/modals/metaData/EditMetaDataPropertyModal.vue
@@ -263,6 +263,8 @@ import {
// icons
import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue'
+import { Metadata } from '../../entities/index.js'
+
export default {
name: 'EditMetaDataPropertyModal',
components: {
@@ -355,16 +357,9 @@ export default {
methods: {
fetchData(id) {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/metadata/${id}`,
- {
- method: 'GET',
- },
- )
- .then((response) => {
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- })
+
+ metadataStore.getOneMetadata(id)
+ .then(({ response }) => {
this.loading = false
})
.catch((err) => {
@@ -374,39 +369,29 @@ export default {
},
updateMetadata(id) {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/metadata/${id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
+
+ const newMetadataItem = new Metadata({
+ ...this.metadata,
+ properties: { // due to bad (no) support for number fields inside nextcloud/vue, parse the text to a number
+ ...this.metadata.properties,
+ [metadataStore.metadataDataKey]: {
+ ...this.metadata.properties[metadataStore.metadataDataKey],
+ minLength: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].minLength) || null,
+ maxLength: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].maxLength) || null,
+ minimum: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].minimum) || null,
+ maximum: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].maximum) || null,
+ multipleOf: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].multipleOf) || null,
+ minItems: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].minItems) || null,
+ maxItems: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].maxItems) || null,
},
- body: JSON.stringify({
- ...this.metadata,
- properties: { // due to bad (no) support for number fields inside nextcloud/vue, parse the text to a number
- ...this.metadata.properties,
- [metadataStore.metadataDataKey]: {
- ...this.metadata.properties[metadataStore.metadataDataKey],
- minLength: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].minLength) || null,
- maxLength: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].maxLength) || null,
- minimum: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].minimum) || null,
- maximum: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].maximum) || null,
- multipleOf: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].multipleOf) || null,
- minItems: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].minItems) || null,
- maxItems: parseFloat(this.metadata.properties[metadataStore.metadataDataKey].maxItems) || null,
- },
- },
- }),
},
- )
- .then((response) => {
+ })
+
+ metadataStore.editMetadata(newMetadataItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the catalogiList
- metadataStore.refreshMetaDataList()
- response.json().then((data) => {
- metadataStore.setMetaDataItem(data)
- })
+
setTimeout(() => {
navigationStore.setModal(false)
this.success = null
diff --git a/src/modals/organisation/AddOrganisationModal.vue b/src/modals/organisation/AddOrganisationModal.vue
index 099710c1..44cb1c1d 100644
--- a/src/modals/organisation/AddOrganisationModal.vue
+++ b/src/modals/organisation/AddOrganisationModal.vue
@@ -25,36 +25,50 @@ import { navigationStore, organisationStore } from '../../store/store.js'
+ :value.sync="organisation.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="organisation.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="organisation.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
+ :value.sync="organisation.oin"
+ :error="!!inputValidation.fieldErrors?.['oin']"
+ :helper-text="inputValidation.fieldErrors?.['oin']?.[0]" />
+ :value.sync="organisation.tooi"
+ :error="!!inputValidation.fieldErrors?.['tooi']"
+ :helper-text="inputValidation.fieldErrors?.['tooi']?.[0]" />
+ :value.sync="organisation.rsin"
+ :error="!!inputValidation.fieldErrors?.['rsin']"
+ :helper-text="inputValidation.fieldErrors?.['rsin']?.[0]" />
+ :value.sync="organisation.pki"
+ :error="!!inputValidation.fieldErrors?.['pki']"
+ :helper-text="inputValidation.fieldErrors?.['pki']?.[0]" />
-
@@ -77,6 +91,7 @@ import {
NcTextField,
} from '@nextcloud/vue'
import Plus from 'vue-material-design-icons/Plus.vue'
+import { Organisation } from '../../entities/index.js'
export default {
name: 'AddOrganisationModal',
@@ -110,6 +125,21 @@ export default {
error: false,
}
},
+ computed: {
+ inputValidation() {
+ const item = new Organisation({
+ ...this.organisation,
+ })
+
+ const result = item.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
updated() {
if (navigationStore.modal === 'organisationAdd' && !this.hasUpdated) {
this.hasUpdated = true
@@ -127,23 +157,16 @@ export default {
addOrganisation() {
this.loading = true
this.error = false
- fetch('/index.php/apps/opencatalogi/api/organisations', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...this.organisation,
- }),
+
+ const organisationItem = new Organisation({
+ ...this.organisation,
})
- .then((response) => {
+
+ organisationStore.addOrganisation(organisationItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the organisationList
- organisationStore.refreshOrganisationList()
- response.json().then((data) => {
- organisationStore.setOrganisationList(data)
- })
+
navigationStore.setSelected('organisations')
// Wait for the user to read the feedback then close the model
const self = this
diff --git a/src/modals/organisation/EditOrganisationModal.vue b/src/modals/organisation/EditOrganisationModal.vue
index 18fb2695..313c95cf 100644
--- a/src/modals/organisation/EditOrganisationModal.vue
+++ b/src/modals/organisation/EditOrganisationModal.vue
@@ -25,36 +25,50 @@ import { navigationStore, organisationStore } from '../../store/store.js'
+ :value.sync="organisation.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="organisation.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="organisation.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
+ :value.sync="organisation.oin"
+ :error="!!inputValidation.fieldErrors?.['oin']"
+ :helper-text="inputValidation.fieldErrors?.['oin']?.[0]" />
+ :value.sync="organisation.tooi"
+ :error="!!inputValidation.fieldErrors?.['tooi']"
+ :helper-text="inputValidation.fieldErrors?.['tooi']?.[0]" />
+ :value.sync="organisation.rsin"
+ :error="!!inputValidation.fieldErrors?.['rsin']"
+ :helper-text="inputValidation.fieldErrors?.['rsin']?.[0]" />
+ :value.sync="organisation.pki"
+ :error="!!inputValidation.fieldErrors?.['pki']"
+ :helper-text="inputValidation.fieldErrors?.['pki']?.[0]" />
-
@@ -77,6 +91,7 @@ import {
NcTextField,
} from '@nextcloud/vue'
import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue'
+import { Organisation } from '../../entities/index.js'
export default {
name: 'EditOrganisationModal',
@@ -92,30 +107,77 @@ export default {
},
data() {
return {
+ organisation: {
+ title: '',
+ summary: '',
+ description: '',
+ oin: '',
+ tooi: '',
+ rsin: '',
+ pki: '',
+ },
loading: false,
success: null,
error: false,
+ hasUpdated: false,
+ }
+ },
+ computed: {
+ inputValidation() {
+ const item = new Organisation({
+ ...this.organisation,
+ })
+
+ const result = item.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
+ mounted() {
+ organisationStore.organisationItem && (this.organisation = organisationStore.organisationItem)
+ },
+ updated() {
+ if (navigationStore.modal === 'editOrganisation' && this.hasUpdated) {
+ if (this.organisation.id === organisationStore.organisationItem.id) return
+ this.hasUpdated = false
+ }
+ if (navigationStore.modal === 'editOrganisation' && !this.hasUpdated) {
+ organisationStore.organisationItem && (this.organisation = organisationStore.organisationItem)
+ this.fetchData(organisationStore.organisationItem.id)
+ this.hasUpdated = true
}
},
methods: {
+ fetchData(id) {
+ this.loading = true
+
+ organisationStore.getOneOrganisation(id)
+ .then(({ response, data }) => {
+ this.organisation = data
+ this.loading = false
+ })
+ .catch((err) => {
+ console.error(err)
+ this.loading = false
+ })
+ },
editOrganisation() {
this.loading = true
this.error = false
- fetch(`/index.php/apps/opencatalogi/api/organisations/${organisationStore.organisationItem.id}`, {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(organisationStore.organisationItem),
+
+ const organisationItem = new Organisation({
+ ...this.organisation,
})
- .then((response) => {
+
+ organisationStore.editOrganisation(organisationItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the organisationList
- organisationStore.refreshOrganisationList()
- response.json().then((data) => {
- organisationStore.setOrganisationItem(data)
- })
+
navigationStore.setSelected('organisations')
// Wait for the user to read the feedback then close the model
const self = this
diff --git a/src/modals/publication/AddPublicationModal.vue b/src/modals/publication/AddPublicationModal.vue
index 74d36263..f2d7a4ea 100644
--- a/src/modals/publication/AddPublicationModal.vue
+++ b/src/modals/publication/AddPublicationModal.vue
@@ -1,5 +1,5 @@
@@ -37,7 +37,7 @@ import { navigationStore, publicationStore } from '../../store/store.js'
Terug naar publicatie type
+ @click="closeModal">
@@ -51,7 +51,8 @@ import { navigationStore, publicationStore } from '../../store/store.js'
Help
@@ -89,35 +90,56 @@ import { navigationStore, publicationStore } from '../../store/store.js'
Publicaties worden gedefineerd door publicatie typen, van welk publicatie type wit u een publicatie aanmaken?
-
+
+
+ Er zijn nog geen publicatieTypes toegevoegd aan deze Catalogus.
+
+
+ Voeg een publicatieType toe om een publicatie aan te maken.
+
+
+
+
+
+ :value.sync="publication.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="publication.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="publication.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
+ :value.sync="publication.reference"
+ :error="!!inputValidation.fieldErrors?.['reference']"
+ :helper-text="inputValidation.fieldErrors?.['reference']?.[0]" />
+ :value.sync="publication.category"
+ :error="!!inputValidation.fieldErrors?.['category']"
+ :helper-text="inputValidation.fieldErrors?.['category']?.[0]" />
+ :value.sync="publication.portal"
+ :error="!!inputValidation.fieldErrors?.['portal']"
+ :helper-text="inputValidation.fieldErrors?.['portal']?.[0]" />
Publicatie datum
+ :value.sync="publication.image"
+ :error="!!inputValidation.fieldErrors?.['image']"
+ :helper-text="inputValidation.fieldErrors?.['image']?.[0]" />
Juridisch
+ :value.sync="publication.license"
+ :error="!!inputValidation.fieldErrors?.['license']"
+ :helper-text="inputValidation.fieldErrors?.['license']?.[0]" />
@@ -161,6 +187,7 @@ import Plus from 'vue-material-design-icons/Plus.vue'
import Help from 'vue-material-design-icons/Help.vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import ArrowLeft from 'vue-material-design-icons/ArrowLeft.vue'
+import { Publication } from '../../entities/index.js'
export default {
name: 'AddPublicationModal',
@@ -191,7 +218,7 @@ export default {
featured: false,
portal: '',
category: '',
- published: new Date(),
+ published: '',
image: '',
data: {},
},
@@ -234,6 +261,23 @@ export default {
})),
}
},
+ inputValidation() {
+ const testClass = new Publication({
+ ...this.publication,
+ catalogi: this.catalogi.value?.id,
+ metaData: this.metaData.value?.source,
+ published: this.publication.published !== '' ? new Date(this.publication.published).toISOString() : new Date().toISOString(),
+ schema: 'https://sadanduseless.b-cdn.net/wp-content/uploads/2018/11/funny-cat-closeup3.jpg',
+ })
+
+ const result = testClass.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
},
watch: {
data: {
@@ -251,6 +295,7 @@ export default {
},
updated() {
if (navigationStore.modal === 'publicationAdd' && !this.hasUpdated) {
+
this.fetchCatalogi()
this.fetchMetaData()
this.hasUpdated = true
@@ -259,30 +304,29 @@ export default {
methods: {
fetchCatalogi() {
this.catalogiLoading = true
- fetch('/index.php/apps/opencatalogi/api/catalogi', {
- method: 'GET',
- })
- .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
+ catalogiStore.getAllCatalogi()
+ .then(({ response, data }) => {
+
+ this.catalogiList = data
+
+ const selectedCatalogus = navigationStore.getTransferData() !== 'ignore selectedCatalogus'
+ ? data.filter((catalogus) => catalogus.id.toString() === navigationStore.selectedCatalogus.toString())[0]
+ : null
+
+ this.catalogi = {
+ options: Object.entries(data).map((catalog) => ({
+ id: catalog[1].id,
+ label: catalog[1].title,
+ })),
+ value: selectedCatalogus
+ ? {
+ id: selectedCatalogus.id,
+ label: selectedCatalogus.title,
+ }
+ : null,
+ }
- this.catalogi = {
- options: Object.entries(data.results).map((catalog) => ({
- id: catalog[1].id,
- label: catalog[1].title,
- })),
- value: selectedCatalogus
- ? {
- id: selectedCatalogus.id,
- label: selectedCatalogus.title,
- }
- : null,
- }
- })
this.catalogiLoading = false
})
.catch((err) => {
@@ -293,17 +337,10 @@ export default {
fetchMetaData() {
this.metaDataLoading = true
- fetch('/index.php/apps/opencatalogi/api/metadata', {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
- this.metaDataList = data.results
- })
- this.metaDataLoading = false
- })
- .catch((err) => {
- console.error(err)
+ metadataStore.getAllMetadata()
+ .then(({ data }) => {
+ this.metaDataList = data
+
this.metaDataLoading = false
})
},
@@ -319,29 +356,19 @@ export default {
this.loading = true
this.error = false
- fetch(
- '/index.php/apps/opencatalogi/api/publications',
- {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...this.publication,
- catalogi: this.catalogi.value.id,
- metaData: this.metaData.value.source,
- }),
- },
- )
- .then((response) => {
+ const publicationItem = new Publication({
+ ...this.publication,
+ catalogi: this.catalogi.value.id,
+ metaData: this.metaData.value.source,
+ published: this.publication.published !== '' ? new Date(this.publication.published).toISOString() : new Date().toISOString(),
+ schema: 'https://sadanduseless.b-cdn.net/wp-content/uploads/2018/11/funny-cat-closeup3.jpg',
+ })
+
+ publicationStore.addPublication(publicationItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the publicationList
- publicationStore.refreshPublicationList()
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- navigationStore.setSelectedCatalogus(data?.catalogi?.id)
- })
+
navigationStore.setSelected('publication')
// Wait for the user to read the feedback then close the model
const self = this
@@ -368,7 +395,7 @@ export default {
featured: false,
portal: '',
category: '',
- published: new Date(),
+ published: '',
image: '',
data: {},
}
diff --git a/src/modals/publication/EditPublicationModal.vue b/src/modals/publication/EditPublicationModal.vue
index 08eeb5a0..361f9584 100644
--- a/src/modals/publication/EditPublicationModal.vue
+++ b/src/modals/publication/EditPublicationModal.vue
@@ -21,23 +21,35 @@ import { navigationStore, publicationStore } from '../../store/store.js'
+ :value.sync="publicationItem.title"
+ :error="!!inputValidation.fieldErrors?.['title']"
+ :helper-text="inputValidation.fieldErrors?.['title']?.[0]" />
+ :value.sync="publicationItem.summary"
+ :error="!!inputValidation.fieldErrors?.['summary']"
+ :helper-text="inputValidation.fieldErrors?.['summary']?.[0]" />
+ :value.sync="publicationItem.description"
+ :error="!!inputValidation.fieldErrors?.['description']"
+ :helper-text="inputValidation.fieldErrors?.['description']?.[0]" />
+ :value.sync="publicationItem.reference"
+ :error="!!inputValidation.fieldErrors?.['reference']"
+ :helper-text="inputValidation.fieldErrors?.['reference']?.[0]" />
+ :value.sync="publicationItem.category"
+ :error="!!inputValidation.fieldErrors?.['category']"
+ :helper-text="inputValidation.fieldErrors?.['category']?.[0]" />
+ :value.sync="publicationItem.portal"
+ :error="!!inputValidation.fieldErrors?.['portal']"
+ :helper-text="inputValidation.fieldErrors?.['portal']?.[0]" />
Publicatie datum
+ :value.sync="publicationItem.image"
+ :error="!!inputValidation.fieldErrors?.['image']"
+ :helper-text="inputValidation.fieldErrors?.['image']?.[0]" />
Juridisch
+ :value.sync="publicationItem.license"
+ :error="!!inputValidation.fieldErrors?.['license']"
+ :helper-text="inputValidation.fieldErrors?.['license']?.[0]" />
@@ -98,6 +115,7 @@ import {
import ContentSaveOutline from 'vue-material-design-icons/ContentSaveOutline.vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import Help from 'vue-material-design-icons/Help.vue'
+import { Publication } from '../../entities/index.js'
export default {
name: 'EditPublicationModal',
@@ -148,6 +166,24 @@ export default {
hasUpdated: false,
}
},
+ computed: {
+ inputValidation() {
+ const testClass = new Publication({
+ ...this.publicationItem,
+ catalogi: this.publicationItem.catalogi.id,
+ metaData: this.publicationItem.metaData.id,
+ published: this.publicationItem.published !== '' ? new Date(this.publicationItem.published).toISOString() : new Date().toISOString(),
+ })
+
+ const result = testClass.validate()
+
+ return {
+ success: result.success,
+ errorMessages: result?.error?.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) || [],
+ fieldErrors: result?.error?.formErrors?.fieldErrors || {},
+ }
+ },
+ },
mounted() {
// publicationStore.publicationItem can be false, so only assign publicationStore.publicationItem to publicationItem if its NOT false
publicationStore.publicationItem && (this.publicationItem = publicationStore.publicationItem)
@@ -166,17 +202,13 @@ export default {
methods: {
fetchData(id) {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/publications/${id}`,
- {
- method: 'GET',
- },
- )
- .then((response) => {
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- this.publicationItem = publicationStore.publicationItem
- })
+
+ publicationStore.getOnePublication(id)
+ .then(({ data }) => {
+ this.publicationItem = {
+ ...data,
+ published: new Date(data.published),
+ }
this.loading = false
})
.catch((err) => {
@@ -186,29 +218,19 @@ export default {
},
updatePublication() {
this.loading = true
- fetch(
- `/index.php/apps/opencatalogi/api/publications/${publicationStore.publicationItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...this.publicationItem,
- id: this.publicationItem.id,
- catalogi: this.publicationItem.catalogi.id,
- metaData: this.publicationItem.metaData.id,
- }),
- },
- )
- .then((response) => {
+
+ const publicationItem = new Publication({
+ ...this.publicationItem,
+ catalogi: this.publicationItem.catalogi.id ?? this.publicationItem.catalogi,
+ metaData: this.publicationItem.metaData.id ?? this.publicationItem.metaData,
+ published: this.publicationItem.published !== '' ? new Date(this.publicationItem.published).toISOString() : new Date().toISOString(),
+ })
+
+ publicationStore.editPublication(publicationItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the catalogiList
- publicationStore.refreshPublicationList()
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- })
+
navigationStore.setSelected('publication')
const self = this
diff --git a/src/modals/publicationData/AddPublicationDataModal.vue b/src/modals/publicationData/AddPublicationDataModal.vue
index 6a22c780..fec71069 100644
--- a/src/modals/publicationData/AddPublicationDataModal.vue
+++ b/src/modals/publicationData/AddPublicationDataModal.vue
@@ -4,6 +4,7 @@ import { navigationStore, publicationStore } from '../../store/store.js'
@@ -204,12 +205,14 @@ import {
NcLoadingIcon,
NcSelect,
} from '@nextcloud/vue'
-import { z } from 'zod'
-import validator from 'validator'
+import { verifyInput as _verifyInput } from './verifyInput.js'
+import { setDefaultValue as _setDefaultValue } from './setDefaultValue.js'
// icons
import Plus from 'vue-material-design-icons/Plus.vue'
+import { Publication } from '../../entities/index.js'
+
export default {
name: 'AddPublicationDataModal',
components: {
@@ -244,7 +247,7 @@ export default {
getFilteredMetadataProperties() {
if (!publicationStore.publicationMetaData?.properties) return []
return Object.values(publicationStore.publicationMetaData?.properties)
- .filter((prop) => !Object.keys(publicationStore.publicationItem?.data).includes(prop.title))
+ .filter((prop) => !Object.keys(publicationStore.publicationItem?.data ?? {}).includes(prop.title))
},
/**
* based on the result `getFilteredMetadataProperties` gives AND the selected value in the eigenschappen dropdown,
@@ -255,7 +258,7 @@ export default {
* @return {object | null} A single metadata properties object or null
*/
getSelectedMetadataProperty() {
- return this.getFilteredMetadataProperties.filter((prop) => prop?.title === this.eigenschappen.value?.label)[0] || null
+ return this.getFilteredMetadataProperties.find((prop) => prop?.title ? prop?.title === this.eigenschappen.value?.label : null) || null
},
mapMetadataEigenschappen() {
if (publicationStore.publicationMetaData) {
@@ -289,295 +292,7 @@ export default {
* @see getSelectedMetadataProperty
*/
verifyInput() {
- const selectedProperty = this.getSelectedMetadataProperty
- if (!selectedProperty) return {}
-
- let schema = z.any()
-
- // TYPE
- if (selectedProperty.type === 'string') {
- schema = z.string()
- }
- if (selectedProperty.type === 'number') {
- schema = z.number()
- }
- if (selectedProperty.type === 'integer') {
- schema = z.number()
- }
- if (selectedProperty.type === 'object') {
- schema = z.string().refine((val) => {
- try {
- JSON.parse(val)
- return true
- } catch (error) {
- return false
- }
- }, 'Dit is niet een geldige object')
- }
- if (selectedProperty.type === 'array') {
- schema = z.array(z.string())
- }
- if (selectedProperty.type === 'boolean') {
- schema = z.boolean()
- }
- if (selectedProperty.type === 'dictionary') {
- schema = z.string() // its not known what a dictionary is yet, so this is here as a little failsafe
- }
-
- // FORMAT - you only want format to be used on strings, this may change in the future
- if (selectedProperty.type === 'string') {
- if (selectedProperty.format === 'date') {
- schema = schema.datetime()
- }
- if (selectedProperty.format === 'time') {
- schema = schema.datetime()
- }
- if (selectedProperty.format === 'date-time') {
- schema = schema.datetime()
- }
- if (selectedProperty.format === 'uuid') {
- // schema = schema.uuid({ message: 'Dit is geen geldige UUID' })
- schema = schema.refine(validator.isUUID, { message: 'Dit is geen geldige UUID' })
- }
- if (selectedProperty.format === 'email') {
- // schema = schema.email({ message: 'Dit is geen geldige Email' })
- schema = schema.refine(validator.isEmail, { message: 'Dit is geen geldige Email' })
- }
- if (selectedProperty.format === 'idn-email') {
- // schema = schema.email({ message: 'Dit is geen geldige Email' })
- schema = schema.refine(validator.isEmail, { message: 'Dit is geen geldige IDN-Email' })
- }
- if (selectedProperty.format === 'hostname') {
- schema = schema.regex(
- /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)+([A-Za-z]|[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9])$/g,
- { message: 'Dit is geen geldige hostname' },
- )
- }
- if (selectedProperty.format === 'idn-hostname') {
- schema = schema.regex(
- /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)+([A-Za-z]|[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9])$/g,
- { message: 'Dit is geen geldige IDN-hostname' },
- )
- }
- if (selectedProperty.format === 'ipv4') {
- // schema = schema.ip({ version: 'v4', message: 'Dit is geen geldige ipv4' })
- schema = schema.refine((val) => validator.isIP(val, 4), { message: 'Dit is geen geldige ipv4' })
- }
- if (selectedProperty.format === 'ipv6') {
- // schema = schema.ip({ version: 'v6', message: 'Dit is geen geldige ipv6' })
- schema = schema.refine((val) => validator.isIP(val, 6), { message: 'Dit is geen geldige ipv6' })
- }
- if (selectedProperty.format === 'url') {
- schema = schema.refine(
- (val) => validator.isURL(val, { require_protocol: true }),
- { message: 'Dit is geen geldige URL' },
- )
- }
- if (selectedProperty.format === 'uri') {
- // schema = schema.url({ message: 'Dit is geen geldige URI' })
- schema = schema.refine(
- (val) => validator.isURL(val, { require_protocol: true }),
- { message: 'Dit is geen geldige URI' },
- )
- }
- if (selectedProperty.format === 'uri-reference') {
- // schema = schema.url({ message: 'Dit is geen geldige URI-reference' })
- schema = schema.refine(
- (val) => validator.isURL(val, { require_protocol: true }),
- { message: 'Dit is geen geldige URI-reference' },
- )
- }
- if (selectedProperty.format === 'iri') {
- // schema = schema.url({ message: 'Dit is geen geldige IRI' })
- schema = schema.refine(
- (val) => validator.isURL(val, { require_protocol: true }),
- { message: 'Dit is geen geldige IRI' },
- )
- }
- if (selectedProperty.format === 'iri-reference') {
- // schema = schema.url({ message: 'Dit is geen geldige IRI-reference' })
- schema = schema.refine(
- (val) => validator.isURL(val, { require_protocol: true }),
- { message: 'Dit is geen geldige IRI-reference' },
- )
- }
- if (selectedProperty.format === 'uri-template') {
- // schema = schema.url({ message: 'Dit is geen geldige URI-template' })
- schema = schema.refine(
- (val) => validator.isURL(val, { require_protocol: true }),
- { message: 'Dit is geen geldige URI-template' },
- )
- }
- if (selectedProperty.format === 'json-pointer') {
- schema = schema.refine((val) => {
- try {
- JSON.parse(val)
- return true
- } catch (error) {
- return false
- }
- }, 'Dit is niet een geldige json-pointer')
- }
- if (selectedProperty.format === 'regex') {
- schema = schema.refine((val) => {
- try {
- RegExp(val)
- return true
- } catch (error) {
- return false
- }
- }, 'Dit is niet een geldige regex')
- }
- if (selectedProperty.format === 'binary') {
- schema = schema.regex(/^[0|1]*$/g, 'Dit is geen geldige binair')
- }
- if (selectedProperty.format === 'byte') {
- schema = schema.regex(/^([0|1]{8})*$/g, 'Dit is geen geldige byte')
- }
- if (selectedProperty.format === 'rsin') {
- schema = schema.regex(/^(\d{9})$/g, 'Dit is geen geldige RSIN-nummer')
- }
- if (selectedProperty.format === 'kvk') {
- schema = schema.regex(/^(\d{8})$/g, 'Dit is geen geldige KVK-nummer')
- }
- if (selectedProperty.format === 'bsn') {
- schema = schema.regex(/^(\d{9})$/g, 'Dit is geen geldige BSN-nummer')
- }
- if (selectedProperty.format === 'oidn') {
- schema = schema.regex(/^\d{8,12}$/g, 'Dit is geen geldige OIDN-nummer')
- }
- if (selectedProperty.format === 'telephone') {
- schema = schema.refine(validator.isMobilePhone, { message: 'Dit is geen geldige telephone-nummer' })
- }
- }
-
- // GENERIC RULES
- if (selectedProperty.pattern) {
- // check is the regex given is valid to avoid any issues
- let isValidRegex = false
- try {
- RegExp(selectedProperty.pattern)
- isValidRegex = true
- } catch (err) {
- isValidRegex = false
- }
-
- if (isValidRegex) {
- const regexPattern = new RegExp(selectedProperty.pattern)
-
- schema = schema.refine((val) => {
- if (Array.isArray(val)) {
- // Validate each string in the array
- return val.every((item) => regexPattern.test(item))
- } else {
- // Validate single string
- return regexPattern.test(val)
- }
- }, { message: 'Voldoet niet aan het vereiste patroon' })
- }
- }
- // number / integer
- if (selectedProperty.type === 'number' || selectedProperty.type === 'integer') {
- // exclusiveMin / exclusiveMax are a boolean, which you can add to a number to add 1 (e.g: 1 + true = 2),
- // this is a stupid simple way to implement what the stoplight is expecting
- // https://conduction.stoplight.io/docs/open-catalogi/5og7tj13bkzj5-create-metadata
- if (selectedProperty.minimum) {
- const minimum = selectedProperty.minimum
- schema = schema.min(minimum + selectedProperty.exclusiveMin, { message: `Minimaal ${minimum + selectedProperty.exclusiveMin}` })
- }
- if (selectedProperty.maximum) {
- const maximum = selectedProperty.maximum
- schema = schema.max(maximum - selectedProperty.exclusiveMax, { message: `Maximaal ${maximum - selectedProperty.exclusiveMax}` })
- }
- if (selectedProperty.multipleOf) {
- const multipleOf = selectedProperty.multipleOf
- schema = schema.refine((val) => val % multipleOf === 0, `${this.value} is niet een veelvoud van ${multipleOf}`)
- }
- } else if (selectedProperty.type === 'array') { // TYPE : ARRAY
- if (selectedProperty.minItems) {
- const minItems = selectedProperty.minItems
- schema = schema.min(minItems, { message: `Minimale hoeveelheid: ${minItems}` })
- }
- if (selectedProperty.maxItems) {
- const maxItems = selectedProperty.maxItems
- schema = schema.max(maxItems, { message: `Maximale hoeveelheid: ${maxItems}` })
- }
- } else { // Anything else
- if (selectedProperty.minLength) {
- const minLength = selectedProperty.minLength
- schema = schema.min(minLength, { message: `Minimale lengte: ${minLength}` })
- }
- if (selectedProperty.maxLength) {
- const maxLength = selectedProperty.maxLength
- schema = schema.max(maxLength, { message: `Maximale lengte: ${maxLength}` })
- }
- }
-
- // REQUIRED CHECK
- if (selectedProperty.required) {
- if (selectedProperty.type === 'array') {
- schema = schema.and(
- // explanation:
- // if ANY item in the array is not an empty string, it passes
- z.custom((val) => val.some((item) => item.trim() !== ''), { message: 'Deze veld is verplicht' }),
- )
- } else if (selectedProperty.type === 'number') {
- // finite says that ANY number between infinite and -infinite is allowed
- // But NaN is not
- schema = schema.finite({ message: 'Deze veld is verplicht' })
- } else if (selectedProperty.type === 'integer') {
- schema = schema.finite({ message: 'Deze veld is verplicht' })
- } else {
- schema = schema.min // .min() does not exist after .refine(), this has been reported at https://github.com/colinhacks/zod/issues/3725
- ? schema.min(1, { message: 'Deze veld is verplicht' })
- : schema.refine(val => val.length >= 1, { message: 'Deze veld is verplicht' })
- }
- }
- if (!selectedProperty.required) {
- // As the value can NEVER be omitted in this code, which is what `.optional()` does
- // I add a `or()` method with a literal empty array / string to act as optional values
-
- // this array check gives me nightmares, I think it works but please don't touch it
- if (selectedProperty.type === 'array') {
- schema = schema.or( // an empty array is always parsed as ['']
- z.custom((val) => val.length === 1 && val[0].trim() === ''),
- )
- } else if (selectedProperty.type === 'number') {
- schema = schema.or(z.nan())
- } else if (selectedProperty.type === 'integer') {
- schema = schema.or(z.nan())
- } else {
- schema = schema.or(z.literal(''))
- }
- }
-
- // RUN TESTS
- let result
- switch (selectedProperty.type) {
- case 'string':{
- if (['date', 'time', 'date-time'].includes(selectedProperty.format)) {
- result = schema.safeParse(this.value.toISOString())
- } else result = schema.safeParse(this.value)
- break
- }
- case 'array':{
- result = schema.safeParse(this.value.split(/ *, */g)) // split on , to make an array
- break
- }
- case 'number':
- case 'integer':{
- result = schema.safeParse(parseFloat(this.value))
- break
- }
- default: {
- result = schema.safeParse(this.value)
- }
- }
-
- return {
- success: result.success,
- helperText: result?.error?.[0]?.message || result?.error?.issues?.[0].message || false,
- }
+ return _verifyInput(this.getSelectedMetadataProperty, this.value)
},
},
watch: {
@@ -588,100 +303,36 @@ export default {
},
methods: {
/**
- * Accepts the selected metadata property or nothing, and changes the value property in `data()` to the default value from the property.
+ * Accepts the selected metadata property, and changes the value property in `data()` to the default value from the property.
*
- * Depending on the property.type, it will put in specialized data, such as `object` or 'boolean'.
+ * Depending on the property.type, it will put in specialized data, such as `object` or `boolean`.
*
* This function only runs when the selected metadata property changes
* @param {object} SelectedMetadataProperty The metadata property Object containing the rules
* @see getSelectedMetadataProperty
*/
- setDefaultValue(SelectedMetadataProperty = null) {
- const prop = SelectedMetadataProperty || this.getSelectedMetadataProperty
- if (!prop) return
-
- switch (prop.type) {
- case 'string': {
- if (prop.format === 'date' || prop.format === 'time' || prop.format === 'date-time') {
- const isValidDate = !isNaN(new Date(prop.default))
-
- console.log('Set default value to Date ', isValidDate ? prop.default : '')
- this.value = new Date(isValidDate ? prop.default : new Date())
- break
- } else {
- console.log('Set default value to ', prop.default)
- this.value = prop.default
- break
- }
- }
-
- case 'object': {
- console.log('Set default value to Object ', prop.default)
- this.value = typeof prop.default === 'object'
- ? JSON.stringify(prop.default)
- : prop.default
- break
- }
-
- case 'array': {
- console.log('Set default value to Array ', prop.default)
- this.value = Array.isArray(prop.default) ? (prop.default.join(', ') || '') : prop.default
- break
- }
-
- case 'boolean': {
- console.log('Set default value to Boolean ', prop.default)
- const isTrueSet = typeof prop.default === 'boolean'
- ? prop.default
- : prop.default?.toLowerCase() === 'true'
- this.value = isTrueSet
- break
- }
-
- case 'number':
- case 'integer': {
- console.log('Set default value to Number ', prop.default)
- this.value = prop.default || 0
- break
- }
-
- default:
- console.log('Set default value to ', prop.default)
- this.value = prop.default
- break
- }
+ setDefaultValue(SelectedMetadataProperty) {
+ this.value = _setDefaultValue(SelectedMetadataProperty)
},
AddPublicatieEigenschap() {
this.loading = true
- const bodyData = publicationStore.publicationItem
- bodyData.data[this.eigenschappen.value?.label] = this.value
- delete bodyData.publicationDate
-
- fetch(
- `/index.php/apps/opencatalogi/api/publications/${publicationStore.publicationItem.id}`,
- {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...bodyData,
- catalogi: bodyData.catalogi.id,
- metaData: bodyData.metaData.id,
- }),
- },
- )
- .then((response) => {
+ const publicationClone = { ...publicationStore.publicationItem }
+
+ publicationClone.data[this.eigenschappen.value?.label] = this.value
+ delete publicationClone.publicationDate
+
+ const newPublicationItem = new Publication({
+ ...publicationClone,
+ catalogi: publicationClone.catalogi.id ?? publicationClone.catalogi,
+ metaData: publicationClone.metaData.id ?? publicationClone.metaData,
+ })
+
+ publicationStore.editPublication(newPublicationItem)
+ .then(({ response }) => {
this.loading = false
this.success = response.ok
- // Lets refresh the publicationList
- publicationStore.refreshPublicationList()
- response.json().then((data) => {
- publicationStore.setPublicationItem(data)
- })
-
// Wait for the user to read the feedback then close the model
const self = this
setTimeout(function() {
@@ -744,4 +395,12 @@ export default {
display: flex;
gap: 4px;
}
+
+.addPublicationPropertyModal .mx-datepicker {
+ margin-top: 0rem;
+ transition: margin 400ms;
+}
+.addPublicationPropertyModal .mx-datepicker:has(.mx-datepicker-popup) {
+ margin-top: 12rem;
+}
diff --git a/src/modals/publicationData/EditPublicationDataModal.vue b/src/modals/publicationData/EditPublicationDataModal.vue
index e76e86a1..3346a2c2 100644
--- a/src/modals/publicationData/EditPublicationDataModal.vue
+++ b/src/modals/publicationData/EditPublicationDataModal.vue
@@ -4,10 +4,12 @@ import { navigationStore, publicationStore } from '../../store/store.js'
Bewerk publicatie eigenschappen
+
{{ publicationStore.publicationDataKey }}
Publicatie eigenschap succesvol bewerkt
@@ -19,17 +21,169 @@ import { navigationStore, publicationStore } from '../../store/store.js'
{{ error }}
+
+ Deze eigenschap staat gemarkeerd als afgeschaft, hij zal bij een komende versie van het onderliggende publicatie type waarschijnlijk komen te vervallen.
+
+ @click="updatePublication(publication.id)">
@@ -40,21 +194,27 @@ import { navigationStore, publicationStore } from '../../store/store.js'
- {{ success ? 'Sluiten' : 'Annuleer' }}
+ {{ success !== null ? 'Sluiten' : 'Annuleer' }}
+
+
+
diff --git a/src/sidebars/directory/DirectorySideBar.vue b/src/sidebars/directory/DirectorySideBar.vue
index bc5f8337..6a3f0d3d 100644
--- a/src/sidebars/directory/DirectorySideBar.vue
+++ b/src/sidebars/directory/DirectorySideBar.vue
@@ -6,7 +6,7 @@ import { navigationStore, directoryStore, metadataStore } from '../../store/stor
-
@@ -28,7 +28,7 @@ import { navigationStore, directoryStore, metadataStore } from '../../store/stor
-
@@ -36,14 +36,14 @@ import { navigationStore, directoryStore, metadataStore } from '../../store/stor
-
-
-
Deze organisatie is niet gevalideerd met een certificaat.
-
-
-
-
Deze listing heeft geen organisatie.
-
+
+
+
Deze organisatie is niet gevalideerd met een certificaat.
+
+
+
+
Deze listing heeft geen organisatie.
+
Samenvatting:
{{ directoryStore.listingItem?.summery }}
@@ -70,7 +70,7 @@ import { navigationStore, directoryStore, metadataStore } from '../../store/stor
-
@@ -97,7 +97,7 @@ import { navigationStore, directoryStore, metadataStore } from '../../store/stor
Synchroniseren
-
@@ -108,9 +108,9 @@ import { navigationStore, directoryStore, metadataStore } from '../../store/stor
- {{ metadataSingular }}
+ {{ metadataSingular.title ?? metadataSingular.source ?? metadataSingular }}
@@ -141,7 +141,8 @@ export default {
},
data() {
return {
- checkedMetadata: {},
+ checkedMetadataObject: {},
+ switchedListing: false,
listing: '',
loading: false,
syncLoading: false,
@@ -151,24 +152,52 @@ export default {
listingItem() {
return directoryStore.listingItem
},
+ checkedMetadata() {
+ return Object.assign({}, this.checkedMetadataObject)
+ },
},
watch: {
checkedMetadata: {
handler(newValue, oldValue) {
- const metadataUrl = Object.entries(newValue)[0][0]
- const shouldCopyMetadata = Object.entries(newValue)[0][1]
- if (shouldCopyMetadata === true) {
- this.copyMetadata(metadataUrl)
- } else if (shouldCopyMetadata === false && metadataUrl && metadataStore.metaDataList.length > 0) {
- this.deleteMetadata(metadataUrl)
+ // Set new and old values to objects
+ const newValueObject = Object.entries(newValue)
+ let oldValueObject = Object.entries(oldValue)
+
+ // Checks if listing is switched
+ if (this.switchedListing === true) {
+ oldValueObject = []
+ this.switchedListing = false
}
+
+ newValueObject.map((value, idx) => {
+ // If oldValueObject does not exist it means we have selected new listing and not updated a switch so we return
+ if (!oldValueObject.length) return {}
+
+ // Checks which switch has been updated by checking the old value of that switch
+ if (value[1] !== oldValueObject[idx][1]) {
+
+ // Sets metadataUrl and shouldCopyMetaData with the right values
+ const metadataUrl = value[0]
+ const shouldCopyMetadata = value[1]
+
+ if (shouldCopyMetadata === true) {
+ this.copyMetadata(metadataUrl)
+ } else if (shouldCopyMetadata === false && metadataUrl && metadataStore.metaDataList.length > 0) {
+ this.deleteMetadata(metadataUrl)
+ }
+ }
+ return {}
+
+ })
+
},
deep: true,
},
listingItem: {
- handler(newValue, oldValue) {
+ handler(newValue) {
if (newValue !== false && metadataStore?.metaDataList) {
this.loading = true
+ this.switchedListing = true
this.checkMetadataSwitches()
}
},
@@ -199,7 +228,7 @@ export default {
// Check if the metadata URL exists in the metadataStore.metaDataList
const exists = metadataStore.metaDataList.some(metaData => metaData.source === metadataUrl)
// Update the checkedMetadata reactive state
- this.$set(this.checkedMetadata, metadataUrl, exists)
+ this.$set(this.checkedMetadataObject, metadataUrl, exists)
})
}
this.loading = false
@@ -296,6 +325,7 @@ export default {
},
)
.then(() => {
+ directoryStore.refreshListingList()
this.syncLoading = false
})
.catch((err) => {
diff --git a/src/store/modules/catalogi.js b/src/store/modules/catalogi.js
deleted file mode 100644
index eaf47a95..00000000
--- a/src/store/modules/catalogi.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* eslint-disable no-console */
-import { defineStore } from 'pinia'
-import { Catalogi } from '../../entities/index.js'
-
-export const useCatalogiStore = defineStore(
- 'catalogi', {
- state: () => ({
- catalogiItem: false,
- catalogiList: [],
- }),
- actions: {
- setCatalogiItem(catalogiItem) {
- this.catalogiItem = catalogiItem && new Catalogi(catalogiItem)
- console.log('Active catalog item set to ' + catalogiItem && catalogiItem?.id)
- },
- setCatalogiList(catalogiList) {
- this.catalogiList = catalogiList.map(
- (catalogiItem) => new Catalogi(catalogiItem),
- )
- console.log('Catalogi list set to ' + catalogiList.length + ' item')
- },
- /* istanbul ignore next */ // ignore this for Jest until moved into a service
- async refreshCatalogiList(search = null) {
- // @todo this might belong in a service?
- let endpoint = '/index.php/apps/opencatalogi/api/catalogi'
- if (search !== null && search !== '') {
- endpoint = endpoint + '?_search=' + search
- }
- return fetch(endpoint, {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
- this.catalogiList = data.results.map(
- (catalogiItem) => new Catalogi(catalogiItem),
- )
- })
- })
- .catch((err) => {
- console.error(err)
- })
- },
- },
- },
-)
diff --git a/src/store/modules/catalogi.spec.js b/src/store/modules/catalogi.spec.js
deleted file mode 100644
index c954bab4..00000000
--- a/src/store/modules/catalogi.spec.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* eslint-disable no-console */
-import { setActivePinia, createPinia } from 'pinia'
-
-import { useCatalogiStore } from './catalogi.js'
-import { Catalogi, mockCatalogi } from '../../entities/index.js'
-
-describe(
- 'Catalogi Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'sets catalogi item correctly', () => {
- const store = useCatalogiStore()
-
- store.setCatalogiItem(mockCatalogi()[0])
-
- expect(store.catalogiItem).toBeInstanceOf(Catalogi)
- expect(store.catalogiItem).toEqual(mockCatalogi()[0])
-
- expect(store.catalogiItem.validate().success).toBe(true)
- })
-
- it(
- 'sets catalogi list correctly', () => {
- const store = useCatalogiStore()
-
- store.setCatalogiList(mockCatalogi())
-
- expect(store.catalogiList).toHaveLength(mockCatalogi().length)
-
- // list item 1
- expect(store.catalogiList[0]).toBeInstanceOf(Catalogi)
- expect(store.catalogiList[0]).toEqual(mockCatalogi()[0])
-
- expect(store.catalogiList[0].validate().success).toBe(true)
-
- // list item 2
- expect(store.catalogiList[1]).toBeInstanceOf(Catalogi)
- expect(store.catalogiList[1]).toEqual(mockCatalogi()[1])
-
- expect(store.catalogiList[1].validate().success).toBe(true)
-
- // list item 3
- expect(store.catalogiList[2]).toBeInstanceOf(Catalogi)
- expect(store.catalogiList[2]).toEqual(mockCatalogi()[2])
-
- expect(store.catalogiList[2].validate().success).toBe(false)
- })
- })
diff --git a/src/store/modules/catalogi.spec.ts b/src/store/modules/catalogi.spec.ts
new file mode 100644
index 00000000..650d5809
--- /dev/null
+++ b/src/store/modules/catalogi.spec.ts
@@ -0,0 +1,48 @@
+/* eslint-disable no-console */
+import { setActivePinia, createPinia } from 'pinia'
+
+import { useCatalogiStore } from './catalogi'
+import { Catalogi, mockCatalogi } from '../../entities/index.js'
+
+describe('Catalogi Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets catalogi item correctly', () => {
+ const store = useCatalogiStore()
+
+ store.setCatalogiItem(mockCatalogi()[0])
+
+ expect(store.catalogiItem).toBeInstanceOf(Catalogi)
+ expect(store.catalogiItem).toEqual(mockCatalogi()[0])
+
+ expect(store.catalogiItem.validate().success).toBe(true)
+ })
+
+ it('sets catalogi list correctly', () => {
+ const store = useCatalogiStore()
+
+ store.setCatalogiList(mockCatalogi())
+
+ expect(store.catalogiList).toHaveLength(mockCatalogi().length)
+
+ // list item 1
+ expect(store.catalogiList[0]).toBeInstanceOf(Catalogi)
+ expect(store.catalogiList[0]).toEqual(mockCatalogi()[0])
+
+ expect(store.catalogiList[0].validate().success).toBe(true)
+
+ // list item 2
+ expect(store.catalogiList[1]).toBeInstanceOf(Catalogi)
+ expect(store.catalogiList[1]).toEqual(mockCatalogi()[1])
+
+ expect(store.catalogiList[1].validate().success).toBe(true)
+
+ // list item 3
+ expect(store.catalogiList[2]).toBeInstanceOf(Catalogi)
+ expect(store.catalogiList[2]).toEqual(mockCatalogi()[2])
+
+ expect(store.catalogiList[2].validate().success).toBe(false)
+ })
+})
diff --git a/src/store/modules/catalogi.ts b/src/store/modules/catalogi.ts
new file mode 100644
index 00000000..857ee084
--- /dev/null
+++ b/src/store/modules/catalogi.ts
@@ -0,0 +1,160 @@
+/* eslint-disable no-console */
+import { defineStore } from 'pinia'
+import { Catalogi, TCatalogi } from '../../entities/index.js'
+
+const apiEndpoint = '/index.php/apps/opencatalogi/api/catalogi'
+
+interface Options {
+ /**
+ * Do not save the received item to the store, this can be enabled if API calls get run in a loop
+ */
+ doNotSetStore?: boolean
+}
+
+interface CatalogiStoreState {
+ catalogiItem: Catalogi;
+ catalogiList: Catalogi[];
+}
+
+export const useCatalogiStore = defineStore('catalogi', {
+ state: () => ({
+ catalogiItem: null,
+ catalogiList: [],
+ } as CatalogiStoreState),
+ actions: {
+ setCatalogiItem(catalogiItem: TCatalogi) {
+ this.catalogiItem = catalogiItem && new Catalogi(catalogiItem)
+ console.log('Active catalog item set to ' + catalogiItem && catalogiItem?.id)
+ },
+ setCatalogiList(catalogiList: TCatalogi[]) {
+ this.catalogiList = catalogiList.map(
+ (catalogiItem) => new Catalogi(catalogiItem),
+ )
+ console.log('Catalogi list set to ' + catalogiList.length + ' item')
+ },
+ /* istanbul ignore next */
+ async refreshCatalogiList(search: string = null) {
+ // @todo this might belong in a service?
+ let endpoint = apiEndpoint
+ if (search !== null && search !== '') {
+ endpoint = endpoint + '?_search=' + search
+ }
+ return fetch(endpoint, {
+ method: 'GET',
+ })
+ .then((response) => {
+ response.json().then((data) => {
+ this.setCatalogiList(data.results)
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ })
+ },
+ /* istanbul ignore next */
+ async getAllCatalogi(options: Options = {}) {
+ const response = await fetch(
+ `${apiEndpoint}`,
+ { method: 'get' },
+ )
+
+ const rawData = await response.json()
+
+ const data = rawData.results.map((catalogiItem: TCatalogi) => new Catalogi(catalogiItem))
+
+ options.doNotSetStore !== true && this.setCatalogiList(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async getOneCatalogi(id: number, options: Options = {}) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'get' },
+ )
+
+ const data = new Catalogi(await response.json())
+
+ options.doNotSetStore !== true && this.setCatalogiItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async addCatalogi(item: Catalogi) {
+ if (!(item instanceof Catalogi)) {
+ throw Error('Please pass a Catalogi item from the Catalogi class')
+ }
+
+ const validateResult = item.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(apiEndpoint,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Catalogi(await response.json())
+
+ this.refreshCatalogiList()
+ this.setCatalogiItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async editCatalogi(catalogiItem: Catalogi) {
+ if (!(catalogiItem instanceof Catalogi)) {
+ throw Error('Please pass a Catalogi item from the Catalogi class')
+ }
+
+ const validateResult = catalogiItem.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${catalogiItem.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Catalogi(await response.json())
+
+ this.refreshCatalogiList()
+ this.setCatalogiItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deleteCatalogi(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'DELETE' },
+ )
+
+ this.refreshCatalogiList()
+ this.setCatalogiItem(null)
+
+ return { response }
+ },
+ },
+})
diff --git a/src/store/modules/configuration.js b/src/store/modules/configuration.js
deleted file mode 100644
index f64daf7c..00000000
--- a/src/store/modules/configuration.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* eslint-disable no-console */
-import { defineStore } from 'pinia'
-import { Configuration } from '../../entities/index.js'
-
-export const useConfigurationStore = defineStore(
- 'configuration', {
- state: () => ({
- configurationItem: false,
- configurationList: [],
- }),
- actions: {
- setConfigurationItem(configurationItem) {
- this.configurationItem = configurationItem && new Configuration(configurationItem)
- console.log('Active configuration item set to ' + configurationItem)
- },
- /* istanbul ignore next */ // ignore this for Jest until moved into a service
- async refreshConfiguration(search = null) {
- // @todo this might belong in a service?
- let endpoint = '/index.php/apps/opencatalogi/api/configuration'
- if (search !== null && search !== '') {
- endpoint = endpoint + '?_search=' + search
- }
- return fetch(
- endpoint, {
- method: 'GET',
- },
- )
- .then(
- (response) => {
- response.json().then(
- (data) => {
- this.setConfigurationItem(data)
- },
- )
- },
- )
- .catch(
- (err) => {
- console.error(err)
- },
- )
- },
- },
- },
-)
diff --git a/src/store/modules/configuration.spec.js b/src/store/modules/configuration.spec.js
deleted file mode 100644
index 0c86b38b..00000000
--- a/src/store/modules/configuration.spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* eslint-disable no-console */
-import { createPinia, setActivePinia } from 'pinia'
-import { Configuration, mockConfiguration } from '../../entities/index.js'
-import { useConfigurationStore } from './configuration.js'
-
-describe(
- 'Configuration Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'sets configuration item correctly', () => {
- const store = useConfigurationStore()
-
- store.setConfigurationItem(mockConfiguration()[0])
-
- expect(store.configurationItem).toBeInstanceOf(Configuration)
- expect(store.configurationItem).toEqual(mockConfiguration()[0])
- expect(store.configurationItem.validate().success).toBe(true)
-
- store.setConfigurationItem(mockConfiguration()[1])
-
- expect(store.configurationItem).toBeInstanceOf(Configuration)
- expect(store.configurationItem).toEqual(mockConfiguration()[1])
- expect(store.configurationItem.validate().success).toBe(true)
-
- store.setConfigurationItem(mockConfiguration()[2])
-
- expect(store.configurationItem).toBeInstanceOf(Configuration)
- expect(store.configurationItem).toEqual(mockConfiguration()[2])
- expect(store.configurationItem.validate().success).toBe(false)
- },
- )
- },
-)
diff --git a/src/store/modules/configuration.spec.ts b/src/store/modules/configuration.spec.ts
new file mode 100644
index 00000000..32312f74
--- /dev/null
+++ b/src/store/modules/configuration.spec.ts
@@ -0,0 +1,32 @@
+/* eslint-disable no-console */
+import { createPinia, setActivePinia } from 'pinia'
+import { Configuration, mockConfiguration } from '../../entities/index.js'
+import { useConfigurationStore } from './configuration'
+
+describe('Configuration Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets configuration item correctly', () => {
+ const store = useConfigurationStore()
+
+ store.setConfigurationItem(mockConfiguration()[0])
+
+ expect(store.configurationItem).toBeInstanceOf(Configuration)
+ expect(store.configurationItem).toEqual(mockConfiguration()[0])
+ expect(store.configurationItem.validate().success).toBe(true)
+
+ store.setConfigurationItem(mockConfiguration()[1])
+
+ expect(store.configurationItem).toBeInstanceOf(Configuration)
+ expect(store.configurationItem).toEqual(mockConfiguration()[1])
+ expect(store.configurationItem.validate().success).toBe(true)
+
+ store.setConfigurationItem(mockConfiguration()[2])
+
+ expect(store.configurationItem).toBeInstanceOf(Configuration)
+ expect(store.configurationItem).toEqual(mockConfiguration()[2])
+ expect(store.configurationItem.validate().success).toBe(false)
+ })
+})
diff --git a/src/store/modules/configuration.ts b/src/store/modules/configuration.ts
new file mode 100644
index 00000000..3d061d84
--- /dev/null
+++ b/src/store/modules/configuration.ts
@@ -0,0 +1,46 @@
+/* eslint-disable no-console */
+import { defineStore } from 'pinia'
+import { Configuration, TConfiguration } from '../../entities/index.js'
+
+interface ConfigurationStoreState {
+ configurationItem: Configuration;
+ configurationList: Configuration[];
+}
+
+export const useConfigurationStore = defineStore('configuration', {
+ state: () => ({
+ configurationItem: null,
+ configurationList: [],
+ } as ConfigurationStoreState),
+ actions: {
+ setConfigurationItem(configurationItem: TConfiguration) {
+ this.configurationItem = configurationItem && new Configuration(configurationItem)
+ console.log('Active configuration item set to ' + configurationItem)
+ },
+ /* istanbul ignore next */ // ignore this for Jest until moved into a service
+ async refreshConfiguration(search: string = null) {
+ // @todo this might belong in a service?
+ let endpoint = '/index.php/apps/opencatalogi/api/configuration'
+ if (search !== null && search !== '') {
+ endpoint = endpoint + '?_search=' + search
+ }
+ return fetch(
+ endpoint, {
+ method: 'GET',
+ },
+ )
+ .then((response) => {
+ response.json().then(
+ (data) => {
+ this.setConfigurationItem(data)
+ },
+ )
+ })
+ .catch(
+ (err) => {
+ console.error(err)
+ },
+ )
+ },
+ },
+})
diff --git a/src/store/modules/directory.js b/src/store/modules/directory.js
deleted file mode 100644
index 8f301cfc..00000000
--- a/src/store/modules/directory.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* eslint-disable no-console */
-import { defineStore } from 'pinia'
-import { Listing } from '../../entities/index.js'
-
-export const useDirectoryStore = defineStore(
- 'directory', {
- state: () => ({
- listingItem: false,
- listingList: [],
- }),
- actions: {
- setListingItem(listingItem) {
- this.listingItem = listingItem && new Listing(listingItem)
- console.log('Active directory item set to ' + listingItem.id)
- },
- setListingList(listingList) {
- this.listingList = listingList.map(
- (listingItem) => new Listing(listingItem),
- )
- console.log('Active directory item set to ' + listingList.length)
- },
- async refreshListingList(search = null) {
- // @todo this might belong in a service?
- let endpoint = '/index.php/apps/opencatalogi/api/directory'
- if (search !== null && search !== '') {
- endpoint = endpoint + '?_search=' + search
- }
- return fetch(
- endpoint, {
- method: 'GET',
- },
- )
- .then(
- (response) => {
- response.json().then(
- (data) => {
- this.listingList = data.results.map(
- (listingItem) => {
- listingItem.organisation = listingItem?.organisation ? listingItem.organisation : null
- return new Listing(listingItem)
- },
- )
- },
- )
- },
- )
- .catch(
- (err) => {
- console.error(err)
- },
- )
- },
- },
- setListingList(listingList) {
- this.listingList = listingList.map(
- (listingItem) => new Listing(listingItem),
- )
- console.log('Active directory item set to ' + listingList.length)
- },
- /* istanbul ignore next */ // ignore this for Jest until moved into a service
- async refreshListingList(search = null) {
- // @todo this might belong in a service?
- let endpoint = '/index.php/apps/opencatalogi/api/directory'
- if (search !== null && search !== '') {
- endpoint = endpoint + '?_search=' + search
- }
- return fetch(endpoint, {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
- this.listingList = data.results.map(
- (listingItem) => new Listing(listingItem),
- )
- })
- })
- .catch((err) => {
- console.error(err)
- })
- },
- },
-)
diff --git a/src/store/modules/directory.spec.js b/src/store/modules/directory.spec.js
deleted file mode 100644
index e1f61258..00000000
--- a/src/store/modules/directory.spec.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* eslint-disable no-console */
-import { setActivePinia, createPinia } from 'pinia'
-
-import { useDirectoryStore } from './directory.js'
-import { Listing, mockListings } from '../../entities/index.js'
-
-describe(
- 'Directory Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'sets listing item correctly', () => {
- const store = useDirectoryStore()
-
- store.setListingItem(mockListings()[0])
-
- expect(store.listingItem).toBeInstanceOf(Listing)
- expect(store.listingItem).toEqual(mockListings()[0])
-
- expect(store.listingItem.validate().success).toBe(true)
- })
-
- it(
- 'sets listings list correctly', () => {
- const store = useDirectoryStore()
-
- store.setListingList(mockListings())
-
- expect(store.listingList).toHaveLength(mockListings().length)
-
- // list item 1
- expect(store.listingList[0]).toBeInstanceOf(Listing)
- expect(store.listingList[0]).toEqual(mockListings()[0])
-
- expect(store.listingList[0].validate().success).toBe(true)
-
- // list item 2
- expect(store.listingList[1]).toBeInstanceOf(Listing)
- expect(store.listingList[1]).toEqual(mockListings()[1])
-
- expect(store.listingList[1].validate().success).toBe(true)
-
- // list item 3
- expect(store.listingList[2]).toBeInstanceOf(Listing)
- expect(store.listingList[2]).toEqual(mockListings()[2])
-
- expect(store.listingList[2].validate().success).toBe(false)
- })
- })
diff --git a/src/store/modules/directory.spec.ts b/src/store/modules/directory.spec.ts
new file mode 100644
index 00000000..262d9fbd
--- /dev/null
+++ b/src/store/modules/directory.spec.ts
@@ -0,0 +1,48 @@
+/* eslint-disable no-console */
+import { setActivePinia, createPinia } from 'pinia'
+
+import { useDirectoryStore } from './directory'
+import { Listing, mockListings } from '../../entities/index.js'
+
+describe('Directory Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets listing item correctly', () => {
+ const store = useDirectoryStore()
+
+ store.setListingItem(mockListings()[0])
+
+ expect(store.listingItem).toBeInstanceOf(Listing)
+ expect(store.listingItem).toEqual(mockListings()[0])
+
+ expect(store.listingItem.validate().success).toBe(true)
+ })
+
+ it('sets listings list correctly', () => {
+ const store = useDirectoryStore()
+
+ store.setListingList(mockListings())
+
+ expect(store.listingList).toHaveLength(mockListings().length)
+
+ // list item 1
+ expect(store.listingList[0]).toBeInstanceOf(Listing)
+ expect(store.listingList[0]).toEqual(mockListings()[0])
+
+ expect(store.listingList[0].validate().success).toBe(true)
+
+ // list item 2
+ expect(store.listingList[1]).toBeInstanceOf(Listing)
+ expect(store.listingList[1]).toEqual(mockListings()[1])
+
+ expect(store.listingList[1].validate().success).toBe(true)
+
+ // list item 3
+ expect(store.listingList[2]).toBeInstanceOf(Listing)
+ expect(store.listingList[2]).toEqual(mockListings()[2])
+
+ expect(store.listingList[2].validate().success).toBe(false)
+ })
+})
diff --git a/src/store/modules/directory.ts b/src/store/modules/directory.ts
new file mode 100644
index 00000000..fe78ca4c
--- /dev/null
+++ b/src/store/modules/directory.ts
@@ -0,0 +1,85 @@
+/* eslint-disable no-console */
+import { defineStore } from 'pinia'
+import { Listing, TListing } from '../../entities/index.js'
+
+interface DirectoryStoreState {
+ listingItem: Listing;
+ listingList: Listing[];
+}
+
+const apiEndpoint = '/index.php/apps/opencatalogi/api/directory'
+
+export const useDirectoryStore = defineStore('directory', {
+ state: () => ({
+ listingItem: null,
+ listingList: [],
+ } as DirectoryStoreState),
+ actions: {
+ setListingItem(listingItem: TListing) {
+ this.listingItem = listingItem && new Listing(listingItem)
+ console.log('Active directory item set to ' + listingItem.id)
+ },
+ setListingList(listingList: TListing[]) {
+ this.listingList = listingList.map(
+ (listingItem: TListing) => new Listing(listingItem),
+ )
+ console.log('Active directory item set to ' + listingList.length)
+ },
+ /* istanbul ignore next */
+ async refreshListingList(search: string = null) {
+ // @todo this might belong in a service?
+ let endpoint = '/index.php/apps/opencatalogi/api/directory'
+ if (search !== null && search !== '') {
+ endpoint = endpoint + '?_search=' + search
+ }
+ return fetch(endpoint, { method: 'GET' })
+ .then((response) => {
+ response.json()
+ .then((data) => {
+ this.listingList = data.results.map(
+ (listingItem: TListing) => {
+ listingItem.organisation = listingItem?.organisation ? listingItem.organisation : null
+ return new Listing(listingItem)
+ },
+ )
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ })
+ },
+ /* istanbul ignore next */
+ async getOneListing(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'get' },
+ )
+
+ const data = new Listing(await response.json())
+
+ this.setListingItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deleteListing(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'DELETE' },
+ )
+
+ this.refreshListingList()
+ this.setListingItem(null)
+
+ return { response }
+ },
+ },
+})
diff --git a/src/store/modules/metadata.js b/src/store/modules/metadata.js
deleted file mode 100644
index 037e94a4..00000000
--- a/src/store/modules/metadata.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* eslint-disable no-console */
-import { defineStore } from 'pinia'
-import { Metadata } from '../../entities/index.js'
-
-export const useMetadataStore = defineStore(
- 'metadata', {
- state: () => ({
- metaDataItem: false,
- metaDataList: [],
- metadataDataKey: false,
- }),
- actions: {
- setMetaDataItem(metaDataItem) {
- // for backward compatibility
- if (!!metaDataItem && typeof metaDataItem?.properties === 'string') {
- metaDataItem.properties = JSON.parse(metaDataItem.properties)
- }
-
- this.metaDataItem = metaDataItem && new Metadata(metaDataItem)
-
- console.log('Active metadata object set to ' + metaDataItem && metaDataItem.id)
- },
- setMetaDataList(metaDataList) {
- this.metaDataList = metaDataList.map(
- (metadataItem) => new Metadata(metadataItem),
- )
- console.log('Active metadata lest set')
- },
- /* istanbul ignore next */ // ignore this for Jest until moved into a service
- async refreshMetaDataList(search = null) {
- // @todo this might belong in a service?
- let endpoint = '/index.php/apps/opencatalogi/api/metadata'
- if (search !== null && search !== '') {
- endpoint = endpoint + '?_search=' + search
- }
- return fetch(
- endpoint,
- {
- method: 'GET',
- },
- )
- .then(
- (response) => {
- response.json().then(
- (data) => {
- this.metaDataList = data.results.map(
- (metadataItem) => new Metadata(metadataItem),
- )
- return data
- },
- )
- },
- )
- .catch(
- (err) => {
- console.error(err)
- return err
- },
- )
- },
- setMetadataDataKey(metadataDataKey) {
- this.metadataDataKey = metadataDataKey
- console.log('Active metadata data key set to ' + metadataDataKey)
- },
- },
- },
-)
diff --git a/src/store/modules/metadata.spec.js b/src/store/modules/metadata.spec.js
deleted file mode 100644
index 65b77ebd..00000000
--- a/src/store/modules/metadata.spec.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* eslint-disable no-console */
-import { setActivePinia, createPinia } from 'pinia'
-
-import { useMetadataStore } from './metadata.js'
-import { Metadata, mockMetadata } from '../../entities/index.js'
-
-describe(
- 'Metadata Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'sets metadata item correctly', () => {
- const store = useMetadataStore()
-
- store.setMetaDataItem(mockMetadata()[0])
-
- expect(store.metaDataItem).toBeInstanceOf(Metadata)
- expect(store.metaDataItem).toEqual(mockMetadata()[0])
-
- expect(store.metaDataItem.validate().success).toBe(true)
- },
- )
-
- it(
- 'sets metadata item with string "properties" property', () => {
- const store = useMetadataStore()
-
- // stringify json data
- const mockData = mockMetadata()[0]
- mockData.properties = JSON.stringify(mockData.properties)
-
- store.setMetaDataItem(mockData)
-
- expect(store.metaDataItem).toBeInstanceOf(Metadata)
- expect(store.metaDataItem).toEqual(mockData)
-
- expect(store.metaDataItem.validate().success).toBe(true)
- },
- )
-
- it(
- 'sets metadata list correctly', () => {
- const store = useMetadataStore()
-
- store.setMetaDataList(mockMetadata())
-
- expect(store.metaDataList[0]).toBeInstanceOf(Metadata)
- expect(store.metaDataList[0]).toEqual(mockMetadata()[0])
-
- expect(store.metaDataList[0].validate().success).toBe(true)
- },
- )
-
- it(
- 'get metadata property from key', () => {
- const store = useMetadataStore()
-
- store.setMetaDataItem(mockMetadata()[0])
- store.setMetadataDataKey('test')
-
- expect(store.metaDataItem).toEqual(mockMetadata()[0])
- expect(store.metadataDataKey).toBe('test')
- },
- )
- },
-)
diff --git a/src/store/modules/metadata.spec.ts b/src/store/modules/metadata.spec.ts
new file mode 100644
index 00000000..5335ccab
--- /dev/null
+++ b/src/store/modules/metadata.spec.ts
@@ -0,0 +1,59 @@
+/* eslint-disable no-console */
+import { setActivePinia, createPinia } from 'pinia'
+
+import { useMetadataStore } from './metadata'
+import { Metadata, mockMetadata } from '../../entities/index.js'
+
+describe('Metadata Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets metadata item correctly', () => {
+ const store = useMetadataStore()
+
+ store.setMetaDataItem(mockMetadata()[0])
+
+ expect(store.metaDataItem).toBeInstanceOf(Metadata)
+ expect(store.metaDataItem).toEqual(mockMetadata()[0])
+
+ expect(store.metaDataItem.validate().success).toBe(true)
+ })
+
+ it('sets metadata item with string "properties" property', () => {
+ const store = useMetadataStore()
+
+ // stringify json data
+ const mockData = mockMetadata()[0]
+ // @ts-expect-error -- this is for the off chance that properties is a string
+ mockData.properties = JSON.stringify(mockData.properties)
+
+ store.setMetaDataItem(mockData)
+
+ expect(store.metaDataItem).toBeInstanceOf(Metadata)
+ expect(store.metaDataItem).toEqual(mockData)
+
+ expect(store.metaDataItem.validate().success).toBe(true)
+ })
+
+ it('sets metadata list correctly', () => {
+ const store = useMetadataStore()
+
+ store.setMetaDataList(mockMetadata())
+
+ expect(store.metaDataList[0]).toBeInstanceOf(Metadata)
+ expect(store.metaDataList[0]).toEqual(mockMetadata()[0])
+
+ expect(store.metaDataList[0].validate().success).toBe(true)
+ })
+
+ it('get metadata property from key', () => {
+ const store = useMetadataStore()
+
+ store.setMetaDataItem(mockMetadata()[0])
+ store.setMetadataDataKey('test')
+
+ expect(store.metaDataItem).toEqual(mockMetadata()[0])
+ expect(store.metadataDataKey).toBe('test')
+ })
+})
diff --git a/src/store/modules/metadata.ts b/src/store/modules/metadata.ts
new file mode 100644
index 00000000..61b0246e
--- /dev/null
+++ b/src/store/modules/metadata.ts
@@ -0,0 +1,164 @@
+/* eslint-disable no-console */
+import { defineStore } from 'pinia'
+import { Metadata, TMetadata } from '../../entities/index.js'
+
+const apiEndpoint = '/index.php/apps/opencatalogi/api/metadata'
+
+interface MetadataStoreState {
+ metaDataItem: Metadata;
+ metaDataList: Metadata[];
+ metadataDataKey: string;
+}
+
+export const useMetadataStore = defineStore('metadata', {
+ state: () => ({
+ metaDataItem: null,
+ metaDataList: [],
+ metadataDataKey: null,
+ } as MetadataStoreState),
+ actions: {
+ setMetaDataItem(metaDataItem: TMetadata) {
+ // for backward compatibility
+ if (!!metaDataItem && typeof metaDataItem?.properties === 'string') {
+ metaDataItem.properties = JSON.parse(metaDataItem.properties)
+ }
+
+ this.metaDataItem = metaDataItem && new Metadata(metaDataItem)
+
+ console.log('Active metadata object set to ' + metaDataItem && metaDataItem?.id)
+ },
+ setMetaDataList(metaDataList: TMetadata[]) {
+ this.metaDataList = metaDataList.map(
+ (metadataItem) => new Metadata(metadataItem),
+ )
+ console.log('Active metadata lest set')
+ },
+ setMetadataDataKey(metadataDataKey: string) {
+ this.metadataDataKey = metadataDataKey
+ console.log('Active metadata data key set to ' + metadataDataKey)
+ },
+ /* istanbul ignore next */ // ignore this for Jest until moved into a service
+ async refreshMetaDataList(search: string = null) {
+ // @todo this might belong in a service?
+ let endpoint = apiEndpoint
+ if (search !== null && search !== '') {
+ endpoint = endpoint + '?_search=' + search
+ }
+ return fetch(endpoint, { method: 'GET' })
+ .then((response) => {
+ response.json().then((data) => {
+ this.setMetaDataList(data.results)
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ return err
+ })
+ },
+ /* istanbul ignore next */
+ async getAllMetadata() {
+ const response = await fetch(
+ `${apiEndpoint}`,
+ { method: 'get' },
+ )
+
+ const rawData = await response.json()
+
+ const data = rawData.results.map((item: TMetadata) => new Metadata(item))
+
+ this.metaDataList = data
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async getOneMetadata(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'get' },
+ )
+
+ const data = new Metadata(await response.json())
+
+ this.setMetaDataItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async addMetadata(metadataItem: Metadata) {
+ if (!(metadataItem instanceof Metadata)) {
+ throw Error('Please pass a Metadata item from the Metadata class')
+ }
+
+ const validateResult = metadataItem.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(apiEndpoint,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Metadata(await response.json())
+
+ this.refreshMetaDataList()
+ this.setMetaDataItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async editMetadata(metadataItem: Metadata) {
+ if (!(metadataItem instanceof Metadata)) {
+ throw Error('Please pass a Metadata item from the Metadata class')
+ }
+
+ const validateResult = metadataItem.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(`${apiEndpoint}/${metadataItem.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Metadata(await response.json())
+
+ this.refreshMetaDataList()
+ this.setMetaDataItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deleteMetadata(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'DELETE' },
+ )
+
+ this.refreshMetaDataList()
+ this.setMetaDataItem(null)
+
+ return { response }
+ },
+ },
+},
+)
diff --git a/src/store/modules/navigation.js b/src/store/modules/navigation.js
deleted file mode 100644
index 225c8b38..00000000
--- a/src/store/modules/navigation.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* eslint-disable no-console */
-import { defineStore } from 'pinia'
-
-export const useNavigationStore = defineStore(
- 'ui', {
- state: () => ({
- // The currently active menu item, defaults to '' which triggers the dashboard
- selected: 'dashboard',
- // The currently selected catalogi within 'publications'
- selectedCatalogus: false,
- // The currently active modal, managed trough the state to ensure that only one modal can be active at the same time
- modal: false,
- // The currently active dialog
- dialog: false,
- // Any data needed in various models, dialogs, views which cannot be transferred through normal means or without writing crappy/excessive code
- transferData: null,
- }),
- actions: {
- setSelected(selected) {
- this.selected = selected
- console.log('Active menu item set to ' + selected)
- },
- setSelectedCatalogus(selectedCatalogus) {
- this.selectedCatalogus = selectedCatalogus
- console.log('Active catalogus menu set to ' + selectedCatalogus)
- },
- setModal(modal) {
- this.modal = modal
- console.log('Active modal set to ' + modal)
- },
- setDialog(dialog) {
- this.dialog = dialog
- console.log('Active dialog set to ' + dialog)
- },
- setTransferData(data) {
- this.transferData = data
- },
- getTransferData() {
- const tempData = this.transferData
- this.transferData = null
- return tempData
- },
- },
- },
-)
diff --git a/src/store/modules/navigation.spec.js b/src/store/modules/navigation.spec.js
deleted file mode 100644
index 73f2e8ff..00000000
--- a/src/store/modules/navigation.spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* eslint-disable no-console */
-import { setActivePinia, createPinia } from 'pinia'
-
-import { useNavigationStore } from './navigation.js'
-
-describe(
- 'Navigation Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'set current selected view correctly', () => {
- const store = useNavigationStore()
-
- store.setSelected('publication')
- expect(store.selected).toBe('publication')
-
- store.setSelected('catalogi')
- expect(store.selected).toBe('catalogi')
-
- store.setSelected('metadata')
- expect(store.selected).toBe('metadata')
- },
- )
-
- it(
- 'set current selected publication catalogi correctly', () => {
- const store = useNavigationStore()
-
- store.setSelectedCatalogus('7a048bfd-210f-4e93-a1e8-5aa9261740b7')
- expect(store.selectedCatalogus).toBe('7a048bfd-210f-4e93-a1e8-5aa9261740b7')
-
- store.setSelectedCatalogus('dd133c51-89bc-4b06-bdbb-41f4dc07c4f1')
- expect(store.selectedCatalogus).toBe('dd133c51-89bc-4b06-bdbb-41f4dc07c4f1')
-
- store.setSelectedCatalogus('3b1cbee2-756e-4904-a157-29fb0cbe01d3')
- expect(store.selectedCatalogus).toBe('3b1cbee2-756e-4904-a157-29fb0cbe01d3')
- },
- )
-
- it(
- 'set modal correctly', () => {
- const store = useNavigationStore()
-
- store.setModal('editPublication')
- expect(store.modal).toBe('editPublication')
-
- store.setModal('editCatalogi')
- expect(store.modal).toBe('editCatalogi')
-
- store.setModal('editMetadata')
- expect(store.modal).toBe('editMetadata')
- },
- )
-
- it(
- 'set modal correctly', () => {
- const store = useNavigationStore()
-
- store.setDialog('deletePublication')
- expect(store.dialog).toBe('deletePublication')
-
- store.setDialog('deleteCatalogi')
- expect(store.dialog).toBe('deleteCatalogi')
-
- store.setDialog('deleteMetadata')
- expect(store.dialog).toBe('deleteMetadata')
- },
- )
- },
-)
diff --git a/src/store/modules/navigation.spec.ts b/src/store/modules/navigation.spec.ts
new file mode 100644
index 00000000..9fe48896
--- /dev/null
+++ b/src/store/modules/navigation.spec.ts
@@ -0,0 +1,62 @@
+/* eslint-disable no-console */
+import { setActivePinia, createPinia } from 'pinia'
+
+import { useNavigationStore } from './navigation'
+
+describe('Navigation Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('set current selected view correctly', () => {
+ const store = useNavigationStore()
+
+ store.setSelected('publication')
+ expect(store.selected).toBe('publication')
+
+ store.setSelected('catalogi')
+ expect(store.selected).toBe('catalogi')
+
+ store.setSelected('metaData')
+ expect(store.selected).toBe('metaData')
+ })
+
+ it('set current selected publication catalogi correctly', () => {
+ const store = useNavigationStore()
+
+ store.setSelectedCatalogus('7a048bfd-210f-4e93-a1e8-5aa9261740b7')
+ expect(store.selectedCatalogus).toBe('7a048bfd-210f-4e93-a1e8-5aa9261740b7')
+
+ store.setSelectedCatalogus('dd133c51-89bc-4b06-bdbb-41f4dc07c4f1')
+ expect(store.selectedCatalogus).toBe('dd133c51-89bc-4b06-bdbb-41f4dc07c4f1')
+
+ store.setSelectedCatalogus('3b1cbee2-756e-4904-a157-29fb0cbe01d3')
+ expect(store.selectedCatalogus).toBe('3b1cbee2-756e-4904-a157-29fb0cbe01d3')
+ })
+
+ it('set modal correctly', () => {
+ const store = useNavigationStore()
+
+ store.setModal('editPublication')
+ expect(store.modal).toBe('editPublication')
+
+ store.setModal('editCatalogi')
+ expect(store.modal).toBe('editCatalogi')
+
+ store.setModal('editMetadata')
+ expect(store.modal).toBe('editMetadata')
+ })
+
+ it('set dialog correctly', () => {
+ const store = useNavigationStore()
+
+ store.setDialog('deletePublication')
+ expect(store.dialog).toBe('deletePublication')
+
+ store.setDialog('deleteCatalogi')
+ expect(store.dialog).toBe('deleteCatalogi')
+
+ store.setDialog('deleteMetadata')
+ expect(store.dialog).toBe('deleteMetadata')
+ })
+})
diff --git a/src/store/modules/navigation.ts b/src/store/modules/navigation.ts
new file mode 100644
index 00000000..87c7f929
--- /dev/null
+++ b/src/store/modules/navigation.ts
@@ -0,0 +1,51 @@
+/* eslint-disable no-console */
+import { defineStore } from 'pinia'
+
+interface NavigationStoreState {
+ selected: 'dashboard' | 'publication' | 'catalogi' | 'metaData' | 'organisations' | 'themes' | 'search';
+ selectedCatalogus: string;
+ modal: string;
+ dialog: string;
+ transferData: string;
+}
+
+export const useNavigationStore = defineStore('ui', {
+ state: () => ({
+ // The currently active menu item, defaults to '' which triggers the dashboard
+ selected: 'dashboard',
+ // The currently selected catalogi within 'publications'
+ selectedCatalogus: null,
+ // The currently active modal, managed trough the state to ensure that only one modal can be active at the same time
+ modal: null,
+ // The currently active dialog
+ dialog: null,
+ // Any data needed in various models, dialogs, views which cannot be transferred through normal means or without writing crappy/excessive code
+ transferData: null,
+ } as NavigationStoreState),
+ actions: {
+ setSelected(selected: NavigationStoreState['selected']) {
+ this.selected = selected
+ console.log('Active menu item set to ' + selected)
+ },
+ setSelectedCatalogus(selectedCatalogus: string) {
+ this.selectedCatalogus = selectedCatalogus
+ console.log('Active catalogus menu set to ' + selectedCatalogus)
+ },
+ setModal(modal: string) {
+ this.modal = modal
+ console.log('Active modal set to ' + modal)
+ },
+ setDialog(dialog: string) {
+ this.dialog = dialog
+ console.log('Active dialog set to ' + dialog)
+ },
+ setTransferData(transferData: string) {
+ this.transferData = transferData
+ },
+ getTransferData(): string {
+ const tempData = this.transferData
+ this.transferData = null
+ return tempData
+ },
+ },
+})
diff --git a/src/store/modules/organisation.js b/src/store/modules/organisation.js
deleted file mode 100644
index 75416c68..00000000
--- a/src/store/modules/organisation.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* eslint-disable no-console */
-import { defineStore } from 'pinia'
-import { Organisation } from '../../entities/index.js'
-
-export const useOrganisationStore = defineStore(
- 'organisation', {
- state: () => ({
- organisationItem: false,
- organisationList: [],
- }),
- actions: {
- setOrganisationItem(organisationItem) {
- this.organisationItem = organisationItem && new Organisation(organisationItem)
- console.log('Active organisation item set to ' + organisationItem && organisationItem?.id)
- },
- setOrganisationList(organisationList) {
- this.organisationList = organisationList.map(
- (organisationItem) => new Organisation(organisationItem),
- )
- console.log('Organisation list set to ' + organisationList.length + ' items')
- },
- /* istanbul ignore next */ // ignore this for Jest until moved into a service
- async refreshOrganisationList(search = null) {
- // @todo this might belong in a service?
- let endpoint = '/index.php/apps/opencatalogi/api/organisations'
- if (search !== null && search !== '') {
- endpoint = endpoint + '?_search=' + search
- }
- return fetch(
- endpoint, {
- method: 'GET',
- },
- )
- .then(
- (response) => {
- response.json().then(
- (data) => {
- this.setOrganisationList(data.results)
- },
- )
- },
- )
- .catch(
- (err) => {
- console.error(err)
- },
- )
- },
- },
- },
-)
diff --git a/src/store/modules/organisation.spec.js b/src/store/modules/organisation.spec.js
deleted file mode 100644
index 27789233..00000000
--- a/src/store/modules/organisation.spec.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* eslint-disable no-console */
-import { createPinia, setActivePinia } from 'pinia'
-
-import { mockOrganisation, Organisation } from '../../entities/index.js'
-import { useOrganisationStore } from './organisation.js'
-
-describe(
- 'Organisation Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'sets organisation item correctly', () => {
- const store = useOrganisationStore()
-
- store.setOrganisationItem(mockOrganisation()[0])
-
- expect(store.organisationItem).toBeInstanceOf(Organisation)
- expect(store.organisationItem).toEqual(mockOrganisation()[0])
- expect(store.organisationItem.validate().success).toBe(true)
-
- store.setOrganisationItem(mockOrganisation()[1])
-
- expect(store.organisationItem).toBeInstanceOf(Organisation)
- expect(store.organisationItem).toEqual(mockOrganisation()[1])
- expect(store.organisationItem.validate().success).toBe(true)
-
- store.setOrganisationItem(mockOrganisation()[2])
-
- expect(store.organisationItem).toBeInstanceOf(Organisation)
- expect(store.organisationItem).toEqual(mockOrganisation()[2])
- expect(store.organisationItem.validate().success).toBe(false)
- },
- )
-
- it(
- 'sets organisation list correctly', () => {
- const store = useOrganisationStore()
-
- store.setOrganisationList(mockOrganisation())
-
- expect(store.organisationList).toHaveLength(mockOrganisation().length)
-
- expect(store.organisationList[0]).toBeInstanceOf(Organisation)
- expect(store.organisationList[0]).toEqual(mockOrganisation()[0])
- expect(store.organisationList[0].validate().success).toBe(true)
-
- expect(store.organisationList[1]).toBeInstanceOf(Organisation)
- expect(store.organisationList[1]).toEqual(mockOrganisation()[1])
- expect(store.organisationList[1].validate().success).toBe(true)
-
- expect(store.organisationList[2]).toBeInstanceOf(Organisation)
- expect(store.organisationList[2]).toEqual(mockOrganisation()[2])
- expect(store.organisationList[2].validate().success).toBe(false)
- },
- )
- },
-)
diff --git a/src/store/modules/organisation.spec.ts b/src/store/modules/organisation.spec.ts
new file mode 100644
index 00000000..a9938747
--- /dev/null
+++ b/src/store/modules/organisation.spec.ts
@@ -0,0 +1,53 @@
+/* eslint-disable no-console */
+import { createPinia, setActivePinia } from 'pinia'
+
+import { mockOrganisation, Organisation } from '../../entities/index.js'
+import { useOrganisationStore } from './organisation'
+
+describe('Organisation Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets organisation item correctly', () => {
+ const store = useOrganisationStore()
+
+ store.setOrganisationItem(mockOrganisation()[0])
+
+ expect(store.organisationItem).toBeInstanceOf(Organisation)
+ expect(store.organisationItem).toEqual(mockOrganisation()[0])
+ expect(store.organisationItem.validate().success).toBe(true)
+
+ store.setOrganisationItem(mockOrganisation()[1])
+
+ expect(store.organisationItem).toBeInstanceOf(Organisation)
+ expect(store.organisationItem).toEqual(mockOrganisation()[1])
+ expect(store.organisationItem.validate().success).toBe(true)
+
+ store.setOrganisationItem(mockOrganisation()[2])
+
+ expect(store.organisationItem).toBeInstanceOf(Organisation)
+ expect(store.organisationItem).toEqual(mockOrganisation()[2])
+ expect(store.organisationItem.validate().success).toBe(false)
+ })
+
+ it('sets organisation list correctly', () => {
+ const store = useOrganisationStore()
+
+ store.setOrganisationList(mockOrganisation())
+
+ expect(store.organisationList).toHaveLength(mockOrganisation().length)
+
+ expect(store.organisationList[0]).toBeInstanceOf(Organisation)
+ expect(store.organisationList[0]).toEqual(mockOrganisation()[0])
+ expect(store.organisationList[0].validate().success).toBe(true)
+
+ expect(store.organisationList[1]).toBeInstanceOf(Organisation)
+ expect(store.organisationList[1]).toEqual(mockOrganisation()[1])
+ expect(store.organisationList[1].validate().success).toBe(true)
+
+ expect(store.organisationList[2]).toBeInstanceOf(Organisation)
+ expect(store.organisationList[2]).toEqual(mockOrganisation()[2])
+ expect(store.organisationList[2].validate().success).toBe(false)
+ })
+})
diff --git a/src/store/modules/organisation.ts b/src/store/modules/organisation.ts
new file mode 100644
index 00000000..e70e737e
--- /dev/null
+++ b/src/store/modules/organisation.ts
@@ -0,0 +1,153 @@
+/* eslint-disable no-console */
+import { defineStore } from 'pinia'
+import { Organisation, TOrganisation } from '../../entities/index.js'
+
+const apiEndpoint = '/index.php/apps/opencatalogi/api/organisations'
+
+interface OrganisationStoreState {
+ organisationItem: Organisation;
+ organisationList: Organisation[];
+}
+
+export const useOrganisationStore = defineStore('organisation', {
+ state: () => ({
+ organisationItem: null,
+ organisationList: [],
+ } as OrganisationStoreState),
+ actions: {
+ setOrganisationItem(organisationItem: TOrganisation | Organisation) {
+ this.organisationItem = organisationItem && new Organisation(organisationItem)
+ console.log('Active organisation item set to ' + organisationItem && organisationItem?.id)
+ },
+ setOrganisationList(organisationList: TOrganisation[] | Organisation[]) {
+ this.organisationList = organisationList.map(
+ (organisationItem) => new Organisation(organisationItem),
+ )
+ console.log('Organisation list set to ' + organisationList.length + ' items')
+ },
+ /* istanbul ignore next */
+ async refreshOrganisationList(search: string = null) {
+ // @todo this might belong in a service?
+ let endpoint = apiEndpoint
+ if (search !== null && search !== '') {
+ endpoint = endpoint + '?_search=' + search
+ }
+ return fetch(endpoint, {
+ method: 'GET',
+ })
+ .then((response) => {
+ response.json().then((data) => {
+ this.setOrganisationList(data.results)
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ })
+ },
+ /* istanbul ignore next */
+ async getAllOrganisation() {
+ const response = await fetch(
+ `${apiEndpoint}`,
+ { method: 'get' },
+ )
+
+ const rawData = await response.json()
+
+ const data = rawData.results.map((organisation: TOrganisation) => new Organisation(organisation))
+
+ this.organisationList = data
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async getOneOrganisation(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'get' },
+ )
+
+ const data = new Organisation(await response.json())
+
+ this.setOrganisationItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async addOrganisation(organisationItem: Organisation) {
+ if (!(organisationItem instanceof Organisation)) {
+ throw Error('Please pass a Organisation item from the Organisation class')
+ }
+
+ const validateResult = organisationItem.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(apiEndpoint,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Organisation(await response.json())
+
+ this.refreshOrganisationList()
+ this.setOrganisationItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async editOrganisation(organisationItem: Organisation) {
+ if (!(organisationItem instanceof Organisation)) {
+ throw Error('Please pass a Organisation item from the Organisation class')
+ }
+
+ const validateResult = organisationItem.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${organisationItem.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Organisation(await response.json())
+
+ this.refreshOrganisationList()
+ this.setOrganisationItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deleteOrganisation(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'DELETE' },
+ )
+
+ this.refreshOrganisationList()
+ this.setOrganisationItem(null)
+
+ return { response }
+ },
+ },
+})
diff --git a/src/store/modules/publication.js b/src/store/modules/publication.js
deleted file mode 100644
index d3053a50..00000000
--- a/src/store/modules/publication.js
+++ /dev/null
@@ -1,250 +0,0 @@
-/* eslint-disable no-console */
-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
- },
- )
- },
- async getConceptPublications(options = {}) { // @todo this might belong in a service?
- const response = await fetch('/index.php/apps/opencatalogi/api/publications?status=concept',
- { method: 'GET' },
- )
-
- const rawData = await response.json()
-
- const data = rawData.results.map((publicationItem) => new Publication(publicationItem))
-
- options.doNotSetStore !== true && (this.conceptPublications = data)
-
- return { response, data }
- },
- async getConceptAttachments(options = {}) { // @todo this might belong in a service?
- const response = await fetch('/index.php/apps/opencatalogi/api/attachments?status=concept',
- { method: 'GET' },
- )
-
- const rawData = await response.json()
-
- const data = rawData.results.map((attachmentItem) => new Attachment(attachmentItem))
-
- options.doNotSetStore !== true && (this.conceptAttachments = data)
-
- return { response, data }
- },
- // @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
- },
- },
- 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/store/modules/publication.spec.js b/src/store/modules/publication.spec.js
deleted file mode 100644
index c2fefa45..00000000
--- a/src/store/modules/publication.spec.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* eslint-disable no-console */
-import { setActivePinia, createPinia } from 'pinia'
-
-import { usePublicationStore } from './publication.js'
-import { Attachment, mockAttachments, mockPublications, Publication } from '../../entities/index.js'
-
-describe(
- 'Metadata Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'sets publication item correctly', () => {
- const store = usePublicationStore()
-
- store.setPublicationItem(mockPublications()[0])
-
- expect(store.publicationItem).toBeInstanceOf(Publication)
- expect(store.publicationItem).toEqual(mockPublications()[0])
- expect(store.publicationItem.validate().success).toBe(true)
-
- store.setPublicationItem(mockPublications()[1])
-
- expect(store.publicationItem).toBeInstanceOf(Publication)
- expect(store.publicationItem).toEqual(mockPublications()[1])
- expect(store.publicationItem.validate().success).toBe(true)
-
- store.setPublicationItem(mockPublications()[2])
-
- expect(store.publicationItem).toBeInstanceOf(Publication)
- expect(store.publicationItem).toEqual(mockPublications()[2])
- expect(store.publicationItem.validate().success).toBe(false)
- })
-
- it(
- 'sets publication list correctly', () => {
- const store = usePublicationStore()
-
- store.setPublicationList(mockPublications())
-
- expect(store.publicationList).toHaveLength(mockPublications().length)
-
- expect(store.publicationList[0]).toBeInstanceOf(Publication)
- expect(store.publicationList[0]).toEqual(mockPublications()[0])
- expect(store.publicationList[0].validate().success).toBe(true)
-
- expect(store.publicationList[1]).toBeInstanceOf(Publication)
- expect(store.publicationList[1]).toEqual(mockPublications()[1])
- expect(store.publicationList[1].validate().success).toBe(true)
-
- expect(store.publicationList[2]).toBeInstanceOf(Publication)
- expect(store.publicationList[2]).toEqual(mockPublications()[2])
- expect(store.publicationList[2].validate().success).toBe(false)
- })
-
- // TODO: fix this
- it(
- 'set publication data.data property key correctly', () => {
- const store = usePublicationStore()
-
- store.setPublicationDataKey('contactPoint')
-
- expect(store.publicationDataKey).toBe('contactPoint')
- },
- )
-
- it(
- 'set attachment item correctly', () => {
- const store = usePublicationStore()
-
- store.setAttachmentItem(mockAttachments()[0])
-
- expect(store.attachmentItem).toBeInstanceOf(Attachment)
- expect(store.attachmentItem).toEqual(mockAttachments()[0])
- expect(store.attachmentItem.validate().success).toBe(true)
-
- store.setAttachmentItem(mockAttachments()[1])
-
- expect(store.attachmentItem).toBeInstanceOf(Attachment)
- expect(store.attachmentItem).toEqual(mockAttachments()[1])
- expect(store.attachmentItem.validate().success).toBe(true)
-
- store.setAttachmentItem(mockAttachments()[2])
-
- expect(store.attachmentItem).toBeInstanceOf(Attachment)
- expect(store.attachmentItem).toEqual(mockAttachments()[2])
- expect(store.attachmentItem.validate().success).toBe(false)
- })
- })
diff --git a/src/store/modules/publication.spec.ts b/src/store/modules/publication.spec.ts
new file mode 100644
index 00000000..53c13fe0
--- /dev/null
+++ b/src/store/modules/publication.spec.ts
@@ -0,0 +1,84 @@
+/* eslint-disable no-console */
+import { setActivePinia, createPinia } from 'pinia'
+
+import { Attachment, mockAttachments, mockPublications, Publication } from '../../entities/index.js'
+import { usePublicationStore } from './publication'
+
+describe('Metadata Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets publication item correctly', () => {
+ const store = usePublicationStore()
+
+ store.setPublicationItem(mockPublications()[0])
+
+ expect(store.publicationItem).toBeInstanceOf(Publication)
+ expect(store.publicationItem).toEqual(mockPublications()[0])
+ expect(store.publicationItem.validate().success).toBe(true)
+
+ store.setPublicationItem(mockPublications()[1])
+
+ expect(store.publicationItem).toBeInstanceOf(Publication)
+ expect(store.publicationItem).toEqual(mockPublications()[1])
+ expect(store.publicationItem.validate().success).toBe(true)
+
+ store.setPublicationItem(mockPublications()[2])
+
+ expect(store.publicationItem).toBeInstanceOf(Publication)
+ expect(store.publicationItem).toEqual(mockPublications()[2])
+ expect(store.publicationItem.validate().success).toBe(false)
+ })
+
+ it('sets publication list correctly', () => {
+ const store = usePublicationStore()
+
+ store.setPublicationList(mockPublications())
+
+ expect(store.publicationList).toHaveLength(mockPublications().length)
+
+ expect(store.publicationList[0]).toBeInstanceOf(Publication)
+ expect(store.publicationList[0]).toEqual(mockPublications()[0])
+ expect(store.publicationList[0].validate().success).toBe(true)
+
+ expect(store.publicationList[1]).toBeInstanceOf(Publication)
+ expect(store.publicationList[1]).toEqual(mockPublications()[1])
+ expect(store.publicationList[1].validate().success).toBe(true)
+
+ expect(store.publicationList[2]).toBeInstanceOf(Publication)
+ expect(store.publicationList[2]).toEqual(mockPublications()[2])
+ expect(store.publicationList[2].validate().success).toBe(false)
+ })
+
+ it('set publication data.data property key correctly', () => {
+ const store = usePublicationStore()
+
+ store.setPublicationDataKey('contactPoint')
+
+ expect(store.publicationDataKey).toBe('contactPoint')
+ },
+ )
+
+ it('set attachment item correctly', () => {
+ const store = usePublicationStore()
+
+ store.setAttachmentItem(mockAttachments()[0])
+
+ expect(store.attachmentItem).toBeInstanceOf(Attachment)
+ expect(store.attachmentItem).toEqual(mockAttachments()[0])
+ expect(store.attachmentItem.validate().success).toBe(true)
+
+ store.setAttachmentItem(mockAttachments()[1])
+
+ expect(store.attachmentItem).toBeInstanceOf(Attachment)
+ expect(store.attachmentItem).toEqual(mockAttachments()[1])
+ expect(store.attachmentItem.validate().success).toBe(true)
+
+ store.setAttachmentItem(mockAttachments()[2])
+
+ expect(store.attachmentItem).toBeInstanceOf(Attachment)
+ expect(store.attachmentItem).toEqual(mockAttachments()[2])
+ expect(store.attachmentItem.validate().success).toBe(false)
+ })
+})
diff --git a/src/store/modules/publication.ts b/src/store/modules/publication.ts
new file mode 100644
index 00000000..4523c567
--- /dev/null
+++ b/src/store/modules/publication.ts
@@ -0,0 +1,432 @@
+/* eslint-disable no-console */
+import pinia from '../../pinia'
+import { Attachment, Publication, TAttachment, TPublication } from '../../entities/index.js'
+import { defineStore } from 'pinia'
+
+const apiEndpoint = '/index.php/apps/opencatalogi/api/publications'
+
+interface Options {
+ /**
+ * Do not save the received item to the store, this can be enabled if API calls get run in a loop
+ */
+ doNotSetStore?: boolean
+}
+
+interface PublicationStoreState {
+ publicationItem: Publication;
+ publicationMetaData: string;
+ publicationList: Publication[];
+ publicationDataKey: string;
+ attachmentItem: Attachment;
+ attachmentFile: object;
+ publicationAttachments: Attachment[];
+ conceptPublications: Publication[];
+ conceptAttachments: Attachment[];
+}
+
+export const usePublicationStore = defineStore('publication', {
+ state: () => ({
+ publicationItem: null,
+ publicationMetaData: null,
+ publicationList: [],
+ publicationDataKey: null,
+ attachmentItem: null,
+ attachmentFile: null,
+ publicationAttachments: null,
+ conceptPublications: [],
+ conceptAttachments: [],
+ } as PublicationStoreState),
+ actions: {
+ setPublicationItem(publicationItem: Publication | TPublication) {
+ // 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: Publication[] | TPublication[]) {
+ this.publicationList = publicationList.map((publicationItem) => new Publication(publicationItem))
+ console.log('Active publication item set to ' + publicationList.length)
+ },
+ async refreshPublicationList(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ normalSearch: { [key: string]: any }[] = [],
+ advancedSearch: string = null,
+ sortField: string = null,
+ sortDirection: string = null,
+ ) {
+ // @todo this might belong in a service?
+ let endpoint = apiEndpoint
+ 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
+ })
+ },
+ /* istanbul ignore next */
+ async getOnePublication(id: number, options: Options = {}) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'get' },
+ )
+
+ const data = new Publication(await response.json())
+
+ options.doNotSetStore !== true && this.setPublicationItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async addPublication(item: Publication) {
+ if (!(item instanceof Publication)) {
+ throw Error('Please pass a Publication item from the Publication class')
+ }
+
+ const validateResult = item.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(apiEndpoint,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Publication(await response.json())
+
+ this.refreshPublicationList()
+ this.setPublicationItem(data)
+
+ // dynamic import the navigationStore to avoid circular imports
+ const { useNavigationStore } = await import('../modules/navigation')
+ const navigationStore = useNavigationStore(pinia)
+ navigationStore.setSelectedCatalogus(data?.catalogi?.id)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async editPublication(item: Publication) {
+ if (!(item instanceof Publication)) {
+ throw Error('Please pass a Publication item from the Publication class')
+ }
+
+ const validateResult = item.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${item.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Publication(await response.json())
+
+ this.refreshPublicationList()
+ this.setPublicationItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deletePublication(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'DELETE' },
+ )
+
+ this.refreshPublicationList()
+ this.setPublicationItem(null)
+
+ return { response }
+ },
+ /* istanbul ignore next */
+ async downloadPublication(id: number, title: string, type: 'pdf' | 'zip') {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+ if (!type) {
+ throw Error('Passed type is pdf or zip')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}/download`,
+ {
+ method: 'GET',
+ headers: {
+ Accept: `application/${type}`,
+ },
+ },
+ )
+
+ const blob = await response.blob()
+
+ const download = () => {
+ const url = window.URL.createObjectURL(new Blob([blob]))
+ const link = document.createElement('a')
+ link.href = url
+
+ link.setAttribute('download', `${title}.${type.toLowerCase()}`)
+ document.body.appendChild(link)
+ link.click()
+ }
+
+ return { response, blob, download }
+ },
+ // ################################
+ // || ||
+ // || ATTACHMENTS ||
+ // || ||
+ // ################################
+ /* istanbul ignore next */
+ async getPublicationAttachments(id: number) {
+ if (!id) {
+ throw Error('Passed publication id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}/attachments`,
+ { method: 'GET' },
+ )
+
+ const rawData = await response.json()
+
+ const data = rawData.results.map(
+ (attachmentItem: TAttachment) => new Attachment(attachmentItem),
+ )
+
+ this.publicationAttachments = data
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async getOneAttachment(id: number) {
+ if (!id) {
+ throw Error('Passed publication id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}/attachments`,
+ { method: 'get' },
+ )
+
+ const data = new Attachment(await response.json())
+
+ this.setPublicationItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async addAttachment(item: Attachment, publicationItem: Publication = null) {
+ if (!(item instanceof Attachment)) {
+ throw Error('Please pass a Attachment item from the Attachment class')
+ }
+ if (publicationItem !== null && !(publicationItem instanceof Publication)) {
+ throw Error('Please pass a Publication item from the Publication class')
+ }
+
+ item.status = 'Concept'
+ item.published = null
+ delete item.id
+
+ const validateResult = item.validate()
+ if (!validateResult.success) {
+ console.log(validateResult)
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch('/index.php/apps/opencatalogi/api/attachments',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Attachment(await response.json())
+
+ // update the publication to include the ID
+ if (publicationItem) {
+ this.getPublicationAttachments(publicationItem?.id)
+
+ const newPublicationItem = new Publication({
+ ...publicationItem,
+ // @ts-expect-error -- screw you typescript, there is no 'string | number', its just number
+ attachments: [...publicationItem.attachments, data.id],
+ // @ts-expect-error -- because I have to POST a number, but receive a object for catalogi, this causes way to much issues. For the love of god let post and get be the same for once.
+ catalogi: publicationItem.catalogi.id,
+ metaData: publicationItem.metaData,
+ })
+
+ this.editPublication(newPublicationItem)
+ }
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async editAttachment(item: Attachment) {
+ if (!(item instanceof Attachment)) {
+ throw Error('Please pass a Attachment item from the Attachment class')
+ }
+
+ const validateResult = item.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${item.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Attachment(await response.json())
+
+ this.setAttachmentItem(null)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deleteAttachment(id: number, publicationItem: Publication = null) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+ if (publicationItem !== null && !(publicationItem instanceof Publication)) {
+ throw Error('Please pass a Publication item from the Publication class')
+ }
+
+ const response = await fetch(
+ `/index.php/apps/opencatalogi/api/attachments/${id}`,
+ { method: 'DELETE' },
+ )
+
+ if (publicationItem) {
+ this.getPublicationAttachments(publicationItem?.id)
+
+ // remove the deleted attachment id
+ // @ts-expect-error -- parse attachment to int to be sure
+ const filteredAttachments = publicationItem.attachments.filter((attachment) => parseInt(attachment) !== parseInt(this.attachmentItem.id))
+
+ const newPublicationItem = new Publication({
+ ...publicationItem,
+ attachments: [...filteredAttachments],
+ // @ts-expect-error -- banana
+ catalogi: publicationItem.catalogi.id,
+ metaData: publicationItem.metaData,
+ })
+
+ this.editPublication(newPublicationItem)
+ }
+
+ this.setAttachmentItem(null)
+ this.getConceptAttachments()
+
+ return { response }
+ },
+ 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.results.map((publicationItem: TPublication) => new Publication(publicationItem))
+ 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.results.map((attachmentItem: TAttachment) => new Attachment(attachmentItem))
+ return data
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ return err
+ })
+ },
+ setPublicationDataKey(publicationDataKey: string) {
+ this.publicationDataKey = publicationDataKey
+ console.log('Active publication data key set to ' + publicationDataKey)
+ },
+ setAttachmentItem(attachmentItem: Attachment | TAttachment) {
+ this.attachmentItem = attachmentItem && new Attachment(attachmentItem)
+ console.log('Active attachment item set to ' + attachmentItem)
+ },
+ setAttachmentFile(files: object) {
+ this.attachmentFile = files
+ console.log('Active attachment files set to ' + files)
+ },
+ setPublicationMetaData(metaData: string) {
+ this.publicationMetaData = metaData
+ },
+ },
+})
diff --git a/src/store/modules/search.spec.js b/src/store/modules/search.spec.js
deleted file mode 100644
index 240ddda6..00000000
--- a/src/store/modules/search.spec.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* eslint-disable no-console */
-import { createPinia, setActivePinia } from 'pinia'
-
-import { useSearchStore } from './search.js'
-
-describe(
- 'Search Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'set search correctly', () => {
- const store = useSearchStore()
-
- store.setSearch('cata')
- expect(store.search).toBe('cata')
-
- store.setSearch('woo')
- expect(store.search).toBe('woo')
-
- store.setSearch('foo bar')
- expect(store.search).toBe('foo bar')
- },
- )
-
- it(
- 'set search result correctly', () => {
- const store = useSearchStore()
-
- store.setSearchResults(['foo', 'bar', 'bux'])
- expect(store.searchResults).toEqual(['foo', 'bar', 'bux'])
- },
- )
-
- it(
- 'clear search correctly', () => {
- const store = useSearchStore()
-
- store.setSearch('Lorem ipsum dolor sit amet')
- expect(store.search).toBe('Lorem ipsum dolor sit amet')
-
- store.clearSearch()
-
- expect(store.search).toBe('')
- },
- )
- },
-)
diff --git a/src/store/modules/search.spec.ts b/src/store/modules/search.spec.ts
new file mode 100644
index 00000000..7474462b
--- /dev/null
+++ b/src/store/modules/search.spec.ts
@@ -0,0 +1,41 @@
+/* eslint-disable no-console */
+import { createPinia, setActivePinia } from 'pinia'
+
+import { useSearchStore } from './search'
+
+describe('Search Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('set search correctly', () => {
+ const store = useSearchStore()
+
+ store.setSearch('cata')
+ expect(store.search).toBe('cata')
+
+ store.setSearch('woo')
+ expect(store.search).toBe('woo')
+
+ store.setSearch('foo bar')
+ expect(store.search).toBe('foo bar')
+ })
+
+ it('set search result correctly', () => {
+ const store = useSearchStore()
+
+ store.setSearchResults(['foo', 'bar', 'bux'])
+ expect(store.searchResults).toEqual(['foo', 'bar', 'bux'])
+ })
+
+ it('clear search correctly', () => {
+ const store = useSearchStore()
+
+ store.setSearch('Lorem ipsum dolor sit amet')
+ expect(store.search).toBe('Lorem ipsum dolor sit amet')
+
+ store.clearSearch()
+
+ expect(store.search).toBe('')
+ })
+})
diff --git a/src/store/modules/search.js b/src/store/modules/search.ts
similarity index 80%
rename from src/store/modules/search.js
rename to src/store/modules/search.ts
index f98d90b5..3b2a3908 100644
--- a/src/store/modules/search.js
+++ b/src/store/modules/search.ts
@@ -10,24 +10,27 @@ export const useSearchStore = defineStore('search', {
searchError: '',
}),
actions: {
- setSearch(search) {
+ setSearch(search: string) {
this.search = search
console.log('Active search set to ' + search)
},
- setSearchResults(searchResults) {
+ setSearchResults(searchResults: string[]) {
this.searchResults = searchResults
console.log('Active search set to ' + searchResults)
},
/* istanbul ignore next */ // ignore this for Jest until moved into a service
getSearchResults() {
const enabledMetadataIds = Object.entries(this.metadata)
- .filter(([key, value]) => value === true)
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ .filter(([_, value]) => value === true)
.map((metadata) => metadata[0])
const enabledCatalogiIds = Object.entries(this.catalogi)
- .filter(([key, value]) => value === true)
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ .filter(([_, value]) => value === true)
.map((catalogi) => catalogi[0])
+ // @ts-expect-error -- for some reason it gives errors in TS even doh it works
const searchParams = new URLSearchParams({
...(this.search && { _search: this.search }),
...(enabledMetadataIds[0] && { meta_data: enabledMetadataIds }),
diff --git a/src/store/modules/theme.js b/src/store/modules/theme.js
deleted file mode 100644
index d7c204a0..00000000
--- a/src/store/modules/theme.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* eslint-disable no-console */
-import { Theme } from '../../entities/index.js'
-import { defineStore } from 'pinia'
-
-export const useThemeStore = defineStore(
- 'theme', {
- state: () => ({
- themeItem: false,
- themeList: [],
- }),
- actions: {
- setThemeItem(themeItem) {
- this.themeItem = themeItem && new Theme(themeItem)
- console.log('Active theme item set to ' + themeItem && themeItem?.id)
- },
- setThemeList(themeList) {
- this.themeList = themeList.map(
- (themeItem) => new Theme(themeItem),
- )
- console.log('Theme list set to ' + themeList.length + ' items')
- },
- /* istanbul ignore next */ // ignore this for Jest until moved into a service
- async refreshThemeList(search = null) {
- // @todo this might belong in a service?
- let endpoint = '/index.php/apps/opencatalogi/api/themes'
- if (search !== null && search !== '') {
- endpoint = endpoint + '?_search=' + search
- }
- return fetch(
- endpoint, {
- method: 'GET',
- },
- )
- .then(
- (response) => {
- response.json().then(
- (data) => {
- this.setThemeList(data.results)
- },
- )
- },
- )
- .catch(
- (err) => {
- console.error(err)
- },
- )
- },
- },
- },
-)
diff --git a/src/store/modules/theme.spec.js b/src/store/modules/theme.spec.js
deleted file mode 100644
index 75f6a99f..00000000
--- a/src/store/modules/theme.spec.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* eslint-disable no-console */
-import { setActivePinia, createPinia } from 'pinia'
-
-import { useThemeStore } from './theme.js'
-import { mockTheme, Theme } from '../../entities/index.js'
-
-describe(
- 'Theme Store', () => {
- beforeEach(
- () => {
- setActivePinia(createPinia())
- },
- )
-
- it(
- 'sets theme item correctly', () => {
- const store = useThemeStore()
-
- store.setThemeItem(mockTheme()[0])
-
- expect(store.themeItem).toBeInstanceOf(Theme)
- expect(store.themeItem).toEqual(mockTheme()[0])
- expect(store.themeItem.validate().success).toBe(true)
-
- store.setThemeItem(mockTheme()[1])
-
- expect(store.themeItem).toBeInstanceOf(Theme)
- expect(store.themeItem).toEqual(mockTheme()[1])
- expect(store.themeItem.validate().success).toBe(true)
-
- store.setThemeItem(mockTheme()[2])
-
- expect(store.themeItem).toBeInstanceOf(Theme)
- expect(store.themeItem).toEqual(mockTheme()[2])
- expect(store.themeItem.validate().success).toBe(false)
- },
- )
-
- it(
- 'sets theme list correctly', () => {
- const store = useThemeStore()
-
- store.setThemeList(mockTheme())
-
- expect(store.themeList).toHaveLength(mockTheme().length)
-
- expect(store.themeList[0]).toBeInstanceOf(Theme)
- expect(store.themeList[0]).toEqual(mockTheme()[0])
- expect(store.themeList[0].validate().success).toBe(true)
-
- expect(store.themeList[1]).toBeInstanceOf(Theme)
- expect(store.themeList[1]).toEqual(mockTheme()[1])
- expect(store.themeList[1].validate().success).toBe(true)
-
- expect(store.themeList[2]).toBeInstanceOf(Theme)
- expect(store.themeList[2]).toEqual(mockTheme()[2])
- expect(store.themeList[2].validate().success).toBe(false)
- },
- )
- },
-)
diff --git a/src/store/modules/theme.spec.ts b/src/store/modules/theme.spec.ts
new file mode 100644
index 00000000..a0c828bf
--- /dev/null
+++ b/src/store/modules/theme.spec.ts
@@ -0,0 +1,53 @@
+/* eslint-disable no-console */
+import { setActivePinia, createPinia } from 'pinia'
+
+import { useThemeStore } from './theme'
+import { mockTheme, Theme } from '../../entities/index.js'
+
+describe('Theme Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets theme item correctly', () => {
+ const store = useThemeStore()
+
+ store.setThemeItem(mockTheme()[0])
+
+ expect(store.themeItem).toBeInstanceOf(Theme)
+ expect(store.themeItem).toEqual(mockTheme()[0])
+ expect(store.themeItem.validate().success).toBe(true)
+
+ store.setThemeItem(mockTheme()[1])
+
+ expect(store.themeItem).toBeInstanceOf(Theme)
+ expect(store.themeItem).toEqual(mockTheme()[1])
+ expect(store.themeItem.validate().success).toBe(true)
+
+ store.setThemeItem(mockTheme()[2])
+
+ expect(store.themeItem).toBeInstanceOf(Theme)
+ expect(store.themeItem).toEqual(mockTheme()[2])
+ expect(store.themeItem.validate().success).toBe(false)
+ })
+
+ it('sets theme list correctly', () => {
+ const store = useThemeStore()
+
+ store.setThemeList(mockTheme())
+
+ expect(store.themeList).toHaveLength(mockTheme().length)
+
+ expect(store.themeList[0]).toBeInstanceOf(Theme)
+ expect(store.themeList[0]).toEqual(mockTheme()[0])
+ expect(store.themeList[0].validate().success).toBe(true)
+
+ expect(store.themeList[1]).toBeInstanceOf(Theme)
+ expect(store.themeList[1]).toEqual(mockTheme()[1])
+ expect(store.themeList[1].validate().success).toBe(true)
+
+ expect(store.themeList[2]).toBeInstanceOf(Theme)
+ expect(store.themeList[2]).toEqual(mockTheme()[2])
+ expect(store.themeList[2].validate().success).toBe(false)
+ })
+})
diff --git a/src/store/modules/theme.ts b/src/store/modules/theme.ts
new file mode 100644
index 00000000..1ca0d97b
--- /dev/null
+++ b/src/store/modules/theme.ts
@@ -0,0 +1,168 @@
+/* eslint-disable no-console */
+import { Theme, TTheme } from '../../entities/index.js'
+import { defineStore } from 'pinia'
+
+const apiEndpoint = '/index.php/apps/opencatalogi/api/themes'
+
+interface Options {
+ /**
+ * Do not save the received item to the store, this can be enabled if API calls get run in a loop
+ */
+ doNotSetStore?: boolean
+}
+
+interface ThemeStoreState {
+ themeItem: Theme;
+ themeList: Theme[];
+}
+
+export const useThemeStore = defineStore('theme', {
+ state: () => ({
+ themeItem: null,
+ themeList: [],
+ } as ThemeStoreState),
+ actions: {
+ setThemeItem(themeItem: Theme | TTheme) {
+ this.themeItem = themeItem && new Theme(themeItem)
+ console.log('Active theme item set to ' + themeItem && themeItem?.id)
+ },
+ setThemeList(themeList: Theme[] | TTheme[]) {
+ this.themeList = themeList.map(
+ (themeItem) => new Theme(themeItem),
+ )
+ console.log('Theme list set to ' + themeList.length + ' items')
+ },
+ /* istanbul ignore next */ // ignore this for Jest until moved into a service
+ async refreshThemeList(search: string = null) {
+ // @todo this might belong in a service?
+ let endpoint = apiEndpoint
+ if (search !== null && search !== '') {
+ endpoint = endpoint + '?_search=' + search
+ }
+ return fetch(
+ endpoint, {
+ method: 'GET',
+ },
+ )
+ .then(
+ (response) => {
+ response.json().then(
+ (data) => {
+ this.setThemeList(data.results)
+ },
+ )
+ },
+ )
+ .catch(
+ (err) => {
+ console.error(err)
+ },
+ )
+ },
+ /* istanbul ignore next */
+ async getAllThemes(options: Options = {}) {
+ const response = await fetch(
+ `${apiEndpoint}`,
+ { method: 'get' },
+ )
+
+ const rawData = await response.json()
+
+ const data = rawData.results.map((themeItem: TTheme) => new Theme(themeItem))
+
+ options.doNotSetStore !== true && this.setThemeList(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async getOneTheme(id: number, options: Options = {}) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'get' },
+ )
+
+ const data = new Theme(await response.json())
+
+ options.doNotSetStore !== true && this.setThemeItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async addTheme(item: Theme) {
+ if (!(item instanceof Theme)) {
+ throw Error('Please pass a Theme item from the Theme class')
+ }
+
+ const validateResult = item.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(apiEndpoint,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Theme(await response.json())
+
+ this.refreshThemeList()
+ this.setThemeItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async editTheme(themeItem: Theme) {
+ if (!(themeItem instanceof Theme)) {
+ throw Error('Please pass a Theme item from the Theme class')
+ }
+
+ const validateResult = themeItem.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${themeItem.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Theme(await response.json())
+
+ this.refreshThemeList()
+ this.setThemeItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deleteTheme(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'DELETE' },
+ )
+
+ this.refreshThemeList()
+ this.setThemeItem(null)
+
+ return { response }
+ },
+ },
+})
diff --git a/src/store/store.js b/src/store/store.js
index 18c2d3d4..945e95ae 100644
--- a/src/store/store.js
+++ b/src/store/store.js
@@ -1,15 +1,19 @@
-/* eslint-disable no-console */
+/* eslint-disable n/no-missing-import */
+/* eslint-disable import/no-unresolved */
+/* eslint-disable import/extensions */
+// fk these rules above here
+
// The store script handles app wide variables (or state), for the use of these variables and there governing concepts read the design.md
import pinia from '../pinia.js'
-import { useCatalogiStore } from './modules/catalogi.js'
-import { useConfigurationStore } from './modules/configuration.js'
-import { useDirectoryStore } from './modules/directory.js'
-import { useMetadataStore } from './modules/metadata.js'
-import { useNavigationStore } from './modules/navigation.js'
-import { useOrganisationStore } from './modules/organisation.js'
-import { usePublicationStore } from './modules/publication.js'
-import { useSearchStore } from './modules/search.js'
-import { useThemeStore } from './modules/theme.js'
+import { useCatalogiStore } from './modules/catalogi'
+import { useConfigurationStore } from './modules/configuration'
+import { useDirectoryStore } from './modules/directory'
+import { useMetadataStore } from './modules/metadata'
+import { useNavigationStore } from './modules/navigation'
+import { useOrganisationStore } from './modules/organisation'
+import { usePublicationStore } from './modules/publication'
+import { useSearchStore } from './modules/search'
+import { useThemeStore } from './modules/theme'
const navigationStore = useNavigationStore(pinia)
const searchStore = useSearchStore(pinia)
diff --git a/src/views/catalogi/CatalogiDetails.vue b/src/views/catalogi/CatalogiDetails.vue
index 8caea070..b016fa4e 100644
--- a/src/views/catalogi/CatalogiDetails.vue
+++ b/src/views/catalogi/CatalogiDetails.vue
@@ -1,5 +1,5 @@
@@ -55,12 +55,39 @@ import { catalogiStore, metadataStore, navigationStore } from '../../store/store
- {{ catalogi.summary }}
+
+
+
+ Samenvatting:
+ {{ catalogi.summary }}
+
+
+
Organisatie:
+
Loading...
+
+
+ Geen organisatie
+
+
+
+ {{ organisation?.title }}
+
+
+
+
+
+ {{ organisation?.title }}
+
+
+
+
+
+
+
-
- Publiek of alleen bepaalde rollen
-
+
+ Publiek of alleen bepaalde rollen
+
@@ -106,6 +136,7 @@ import {
NcActionButton,
NcLoadingIcon,
NcListItem,
+ NcActionLink,
} from '@nextcloud/vue'
import { BTabs, BTab } from 'bootstrap-vue'
@@ -124,6 +155,7 @@ export default {
NcActionButton,
NcLoadingIcon,
NcListItem,
+ NcActionLink,
},
props: {
catalogiItem: {
@@ -134,6 +166,8 @@ export default {
data() {
return {
catalogi: false,
+ organisation: [],
+ organisationLoading: false,
loading: false,
upToDate: false,
metadataLoading: false,
@@ -142,13 +176,11 @@ export default {
watch: {
catalogiItem: {
handler(newCatalogiItem, oldCatalogiItem) {
- // why this? because when you fetch a new item it changes the reference to said item, which in return causes it to fetch again (a.k.a. infinite loop)
- // run the fetch only once to update the item
if (!this.upToDate || JSON.stringify(newCatalogiItem) !== JSON.stringify(oldCatalogiItem)) {
this.catalogi = newCatalogiItem
- // check if newCatalogiItem is not false
newCatalogiItem && this.fetchData(newCatalogiItem?.id)
this.upToDate = true
+ newCatalogiItem?.organisation ? this.fetchOrganization(newCatalogiItem?.organisation) : this.organisation = false
}
},
deep: true,
@@ -159,11 +191,9 @@ export default {
// check if catalogiItem is not false
catalogiStore.catalogiItem && this.fetchData(catalogiStore.catalogiItem?.id)
+ catalogiStore.catalogiItem.organisation && this.fetchOrganization(catalogiStore.catalogiItem.organisation)
+
this.metadataLoading = true
- metadataStore.refreshMetaDataList()
- .then(() => {
- this.metadataLoading = false
- })
},
methods: {
fetchData(catalogId) {
@@ -178,6 +208,10 @@ export default {
response.json().then((data) => {
catalogiStore.setCatalogiItem(data)
this.catalogi = catalogiStore.catalogiItem
+ metadataStore.refreshMetaDataList()
+ .then(() => {
+ this.metadataLoading = false
+ })
})
this.loading = false
})
@@ -186,10 +220,31 @@ export default {
this.loading = false
})
},
+ fetchOrganization(organisationId, loading) {
+ if (loading) { this.organisationLoading = true }
+
+ fetch(`/index.php/apps/opencatalogi/api/organisations/${organisationId}`, {
+ method: 'GET',
+ })
+ .then((response) => {
+ response.json().then((data) => {
+ this.organisation = data
+ })
+ if (loading) { this.organisationLoading = false }
+ })
+ .catch((err) => {
+ console.error(err)
+ if (loading) { this.organisationLoading = false }
+ })
+ },
filteredMetadata(source) {
if (this.metadataLoading) return null
return metadataStore.metaDataList.filter((metadata) => metadata?.source === source)[0]
},
+ goToOrganisation() {
+ organisationStore.setOrganisationItem(this.organisation)
+ navigationStore.setSelected('organisations')
+ },
openLink(url, type = '') {
window.open(url, type)
},
@@ -265,4 +320,23 @@ h4 {
display: flex;
gap: 4px;
}
+
+.buttonLinkContainer {
+ display: flex;
+ align-items: center;
+}
+
+.catalogDetailGrid {
+ display: grid;
+ grid-template-columns: 1fr;
+}
+
+.catalogDetailGridOrganisation {
+ display: flex;
+ align-items: center;
+}
+
+.catalogDetailGridOrganisationTitle {
+ margin-inline-end: 1ch;
+}
diff --git a/src/views/catalogi/CatalogiList.vue b/src/views/catalogi/CatalogiList.vue
index 7a60e97f..82798fee 100644
--- a/src/views/catalogi/CatalogiList.vue
+++ b/src/views/catalogi/CatalogiList.vue
@@ -42,9 +42,9 @@ import { catalogiStore, navigationStore } from '../../store/store.js'
diff --git a/src/views/directory/DirectoryList.vue b/src/views/directory/DirectoryList.vue
index 048a87df..7af65bf7 100644
--- a/src/views/directory/DirectoryList.vue
+++ b/src/views/directory/DirectoryList.vue
@@ -43,7 +43,8 @@ import { navigationStore, directoryStore } from '../../store/store.js'
:name="listing.name ?? listing.title"
:active="directoryStore.listingItem?.id === listing?.id"
:details="listing?.organisation?.title || 'Geen organisatie'"
- :counter-number="listing?.metadata?.length || 0"
+ :counter-number="listing?.metadata?.length || '0'"
+ :force-display-actions="true"
@click="directoryStore.setListingItem(listing)">
{{ metadata.title }}
- {{ metadata.description }}
+ {{ metadata.description || metadata.summary }}
{
- response.json().then((data) => {
- this.organisation = data
- })
- })
- .catch((err) => {
- console.error(err)
+ organisationStore.getOneOrganisation(id)
+ .then(({ response, data }) => {
+ this.organisation = data
})
},
openLink(url, type = '') {
diff --git a/src/views/organisations/OrganisationIndex.vue b/src/views/organisations/OrganisationIndex.vue
index dbc8c288..912231b2 100644
--- a/src/views/organisations/OrganisationIndex.vue
+++ b/src/views/organisations/OrganisationIndex.vue
@@ -8,7 +8,7 @@ import { navigationStore, organisationStore, searchStore } from '../../store/sto
-
@@ -21,7 +21,7 @@ import { navigationStore, organisationStore, searchStore } from '../../store/sto
-
+
diff --git a/src/views/organisations/OrganisationList.vue b/src/views/organisations/OrganisationList.vue
index fc5af760..b881e8ff 100644
--- a/src/views/organisations/OrganisationList.vue
+++ b/src/views/organisations/OrganisationList.vue
@@ -43,7 +43,7 @@ import { navigationStore, organisationStore } from '../../store/store.js'
:name="organisation.title"
:bold="false"
:force-display-actions="true"
- :active="organisationStore.organisationItem.id === organisation.id"
+ :active="organisationStore.organisationItem?.id === organisation.id"
:details="organisation?.status"
@click="organisationStore.setOrganisationItem(organisation)">
diff --git a/src/views/publications/PublicationDetail.vue b/src/views/publications/PublicationDetail.vue
index e51bf77a..a59b6be7 100644
--- a/src/views/publications/PublicationDetail.vue
+++ b/src/views/publications/PublicationDetail.vue
@@ -41,14 +41,14 @@ import { ref } from 'vue'
Kopiƫren
-
Publiceren
-
@@ -91,56 +91,56 @@ import { ref } from 'vue'
Referentie:
- {{ publicationStore.publicationItem.reference }}
+ {{ publicationStore.publicationItem?.reference }}
Samenvatting:
- {{ publicationStore.publicationItem.summary }}
+ {{ publicationStore.publicationItem?.summary }}
Beschrijving:
- {{ publicationStore.publicationItem.description }}
+ {{ publicationStore.publicationItem?.description }}
Categorie:
- {{ publicationStore.publicationItem.category }}
+ {{ publicationStore.publicationItem?.category }}
Foto:
- {{ publicationStore.publicationItem.image }}
+ {{ publicationStore.publicationItem?.image }}
Thema's:
- {{ publicationStore.publicationItem.themes.join(", ") }}
+ {{ publicationStore.publicationItem?.themes.join(", ") }}
Uitgelicht:
- {{ publicationStore.publicationItem.featured ? "Ja" : "Nee" }}
+ {{ publicationStore.publicationItem?.featured ? "Ja" : "Nee" }}
Licentie:
- {{ publicationStore.publicationItem.license }}
+ {{ publicationStore.publicationItem?.license }}
Status:
- {{ publicationStore.publicationItem.status }}
+ {{ publicationStore.publicationItem?.status }}
Gepubliceerd:
- {{ publicationStore.publicationItem.published }}
+ {{ publicationStore.publicationItem?.published }}
Gewijzigd:
- {{ publicationStore.publicationItem.modified }}
+ {{ publicationStore.publicationItem?.modified }}
Bron:
- {{ publicationStore.publicationItem.source }}
+ {{ publicationStore.publicationItem?.source }}
Catalogi:
@@ -205,7 +205,7 @@ import { ref } from 'vue'
-
+
-
+
Nog geen bijlage toegevoegd
+ v-if="publicationStore.publicationAttachments?.length !== 0 && !publicationStore.publicationAttachments?.length > 0">
// Components
-import { NcActionButton, NcActions, NcButton, NcListItem, NcLoadingIcon, NcNoteCard, NcSelectTags } from '@nextcloud/vue'
+import { NcActionButton, NcActions, NcButton, NcListItem, NcLoadingIcon, NcNoteCard, NcSelectTags, NcActionLink } from '@nextcloud/vue'
import { useFileSelection } from './../../composables/UseFileSelection.js'
import { BTab, BTabs } from 'bootstrap-vue'
import VueApexCharts from 'vue-apexcharts'
@@ -438,6 +438,7 @@ export default {
NcListItem,
NcSelectTags,
NcNoteCard,
+ NcActionLink,
BTab,
BTabs,
apexchart: VueApexCharts,
@@ -487,8 +488,8 @@ export default {
if (!this.upToDate || JSON.stringify(newPublicationItem) !== JSON.stringify(oldPublicationItem)) {
this.publication = publicationStore.publicationItem
- this.fetchCatalogi(publicationStore.publicationItem.catalogi.id)
- this.fetchMetaData(publicationStore.publicationItem.metaData)
+ this.fetchCatalogi(publicationStore.publicationItem?.catalogi.id ?? publicationStore.publicationItem.catalogi)
+ this.fetchMetaData(publicationStore.publicationItem?.metaData)
publicationStore.publicationItem?.id && this.fetchData(publicationStore.publicationItem.id)
}
},
@@ -499,7 +500,7 @@ export default {
mounted() {
this.publication = publicationStore.publicationItem
- this.fetchCatalogi(this.publication.catalogi?.id, true)
+ this.fetchCatalogi(this.publication.catalogi?.id ?? this.publication.catalogi, true)
this.fetchMetaData(publicationStore.publicationItem.metaData, true)
publicationStore.publicationItem?.id && this.fetchData(publicationStore.publicationItem.id)
@@ -507,18 +508,15 @@ export default {
methods: {
fetchData(id) {
// this.loading = true
- fetch(`/index.php/apps/opencatalogi/api/publications/${id}`, {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
- this.publication = data
- // this.oldZaakId = id
- this.fetchCatalogi(data.catalogi.id)
- this.fetchMetaData(data.metaData)
- publicationStore.getPublicationAttachments(id)
- // this.loading = false
- })
+
+ publicationStore.getOnePublication(id, { doNotSetStore: true })
+ .then(({ response, data }) => {
+ this.publication = data
+ // this.oldZaakId = id
+ this.fetchCatalogi(data.catalogi.id ?? data.catalogi)
+ this.fetchMetaData(data.metaData)
+ publicationStore.getPublicationAttachments(id)
+ // this.loading = false
})
.catch((err) => {
console.error(err)
@@ -529,13 +527,10 @@ export default {
fetchCatalogi(catalogiId, loading) {
if (loading) { this.catalogiLoading = true }
- fetch(`/index.php/apps/opencatalogi/api/catalogi/${catalogiId}`, {
- method: 'GET',
- })
- .then((response) => {
- response.json().then((data) => {
- this.catalogi = data
- })
+ catalogiStore.getOneCatalogi(catalogiId, { doNotSetStore: true })
+ .then(({ response, data }) => {
+ this.catalogi = data
+
if (loading) { this.catalogiLoading = false }
})
.catch((err) => {
diff --git a/src/views/publications/PublicationIndex.vue b/src/views/publications/PublicationIndex.vue
index a99d6b2c..397b8807 100644
--- a/src/views/publications/PublicationIndex.vue
+++ b/src/views/publications/PublicationIndex.vue
@@ -8,7 +8,7 @@ import { navigationStore, searchStore, publicationStore } from '../../store/stor
-
@@ -21,7 +21,7 @@ import { navigationStore, searchStore, publicationStore } from '../../store/stor
-
+
diff --git a/src/views/publications/PublicationList.vue b/src/views/publications/PublicationList.vue
index 77d405df..b11f0ce9 100644
--- a/src/views/publications/PublicationList.vue
+++ b/src/views/publications/PublicationList.vue
@@ -84,15 +84,15 @@ import { navigationStore, publicationStore } from '../../store/store.js'
:name="publication.title"
:bold="false"
:force-display-actions="true"
- :active="publicationStore.publicationItem.id === publication.id"
+ :active="publicationStore.publicationItem?.id === publication.id"
:details="publication?.status"
:counter-number="publication?.attachmentCount.toString()"
@click="setActive(publication)">
-
-
-
-
+
+
+
+
{{ publication?.summary }}
@@ -110,13 +110,13 @@ import { navigationStore, publicationStore } from '../../store/store.js'
Kopiƫren
-
+
Publiceren
-
+
@@ -160,7 +160,7 @@ import { navigationStore, publicationStore } from '../../store/store.js'