Skip to content

Commit

Permalink
Merge branch 'release-0.11' into 0.11-fix-importer-without-header
Browse files Browse the repository at this point in the history
  • Loading branch information
v1r0x authored Dec 13, 2024
2 parents fe27d16 + b5c9e85 commit c4b598f
Show file tree
Hide file tree
Showing 30 changed files with 689 additions and 299 deletions.
21 changes: 19 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,26 @@
All notable changes to this project will be documented in this file.

## 0.11
### Added
- Filter and sort functionality on _Entity Type List_
### Fixed
- Missing "Color Dots" of _Entity Type_ (colors are now handled on the Entity Type itself and do no longer rely on the _Map_ Plugin)
- 'Jumping' behavior on floating quick access controls on the _Entity Type List_ (copy, duplicate, delete)
- Attribute Dependency inverted

## 0.10.2
### Fixed
- Date Range _importFrom_ did not return a JSON string
- Richtext editor did not trigger the dirty state on entity
- Certainty warning due to _undefined_ value
- Serial and SQL attributes now have the required value (_v_) and functions (_resetFieldState_, _undirtyField_)
### Changed
- Added tests to _ApiDataImporterTest_ to check if the same columns can be used in multiple attributes
- Row error now also sends the column value, instead of just sending the column name
- Dropdowns in the _Data Importer_ are now sorted alphabetically
- The ErrorList component of the Data Importer in the Frontend now preserves text inside `{{...}}`
- Adjusted colors of Markdown modal buttons

## 0.10.1
### Added
- Option to display attributes in _Data Model Editor_ in groups
Expand All @@ -14,8 +31,8 @@ All notable changes to this project will be documented in this file.
- selects the first choice (if there is **only one choice** in the dropdown)*
- selects the exact match (**case insensitive**; e.g. "apple" + `Tab` will select the available choice "apple", but also "Apple")*
- nothing and focuses the next attribute (default)
- * Selected elements will be marked with a blue (Tab) badge
- Pressing `Delete` inside _Single Choice Dropdowns_ will clear the element
- * Selected elements will be marked with a blue (Tab) badge
- Pressing `Delete` inside _Single Choice Dropdowns_ will clear the element
- Importer now automatically removes BOM if present
- Better readable format for error message on validation
- Renamed _fromImport_ to _parseImport_ on the attribute classses. The base class now by default imports the passed string, removing redundancies on the string-based classes.
Expand Down
8 changes: 4 additions & 4 deletions app/AttributeTypes/DaterangeAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ public static function parseImport(int|float|bool|string $data) : mixed {
throw InvalidDataException::requireBefore($start, $end);
}

return [
"start" => $start,
"end" => $end,
];
return json_encode([
$start,
$end,
]);
}

public static function unserialize(mixed $data) : mixed {
Expand Down
3 changes: 2 additions & 1 deletion app/EntityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ public function getActivitylogOptions() : LogOptions
->logOnlyDirty();
}

public function setRelationInfo($isRoot = false, $subTypes = []) {
public function setRelationInfo($color, $isRoot = false, $subTypes = []) {
$this->is_root = $isRoot;
$this->color = $color;
EntityTypeRelation::where('parent_id', $this->id)->delete();
foreach($subTypes as $type) {
$relation = new EntityTypeRelation();
Expand Down
19 changes: 11 additions & 8 deletions app/Http/Controllers/EditorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,12 @@ public function addEntityType(Request $request) {

$curl = $request->get('concept_url');
$is_root = sp_parse_boolean($request->get('is_root'));
$cType = new EntityType();
$cType->thesaurus_url = $curl;
$cType->is_root = $is_root;
$cType->save();
$cType = EntityType::find($cType->id);
$entityType = new EntityType();
$entityType->thesaurus_url = $curl;
$entityType->is_root = $is_root;
$entityType->color = sprintf('#%06X', mt_rand(0, 0xFFFFFF));
$entityType->save();
$entityType = EntityType::find($entityType->id);

// TODO:: Reimplement in plugin [SO]
//
Expand All @@ -167,7 +168,7 @@ public function addEntityType(Request $request) {

// $cType->load('layer');

return response()->json($cType, 201);
return response()->json($entityType, 201);
}

public function setRelationInfo(Request $request, $id) {
Expand All @@ -179,7 +180,8 @@ public function setRelationInfo(Request $request, $id) {
}
$this->validate($request, [
'is_root' => 'boolean_string',
'sub_entity_types' => 'array'
'sub_entity_types' => 'array',
'color' => 'color',
]);
try {
$entityType = EntityType::findOrFail($id);
Expand All @@ -190,7 +192,8 @@ public function setRelationInfo(Request $request, $id) {
}
$is_root = $request->get('is_root');
$subs = $request->get('sub_entity_types');
$entityType->setRelationInfo($is_root, $subs);
$color = $request->get('color');
$entityType->setRelationInfo($color, $is_root, $subs);
return response()->json(null, 204);
}

Expand Down
29 changes: 16 additions & 13 deletions app/Import/EntityImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class EntityImporter {

private $metadata;
private array $attributesMap;
private array $attributeAttributeMap = [];
private array $attributeIdToAttributeValue = [];
private int $entityTypeId;
private string $nameColumn;
private ?string $parentColumn = null;
Expand Down Expand Up @@ -157,7 +157,7 @@ private function verifyEntityType($entityTypeId): bool {
private function verifyAttributeMapping($headers): bool {
$nameErrors = [];
$indexErrors = [];
foreach($this->attributesMap as $attribute => $column) {
foreach($this->attributesMap as $attributeId => $column) {
$column = trim($column);
if($column == "") {
continue;
Expand All @@ -167,27 +167,26 @@ private function verifyAttributeMapping($headers): bool {
array_push($nameErrors, $column);
}

$attr = Attribute::find($attribute);
$attr = Attribute::find($attributeId);
if(!$attr) {
array_push($indexErrors, $attribute);
array_push($indexErrors, $attributeId);
} else {
$this->attributeAttributeMap[$column] = $attr;
$this->attributeIdToAttributeValue[$attributeId] = $attr;
}
}

$valid = true;
if(count($indexErrors) > 0) {
$this->resolver->conflict(__("entity-importer.attribute-id-does-not-exist", ["attributes" => implode(", ", $indexErrors)]));
$valid = false;
}

if(count($nameErrors) > 0) {
$this->resolver->conflict(__("entity-importer.attribute-column-does-not-exist", ["columns" => implode(", ", $nameErrors)]));
$valid = false;
}

if(count($indexErrors) > 0 || count($nameErrors) > 0) {
return false;
} else {
return true;
}
return $valid;
}

private function validateName($row, $rowIndex): bool {
Expand Down Expand Up @@ -243,18 +242,22 @@ private function validateLocation($row, $rowIndex): bool {

private function validateAttributesInRow($row, $index): bool {
$errors = [];
foreach($this->attributeAttributeMap as $column => $attribute) {
foreach($this->attributeIdToAttributeValue as $attributeId => $attribute) {
try {
$column = $this->attributesMap[$attributeId];
$datatype = $attribute->datatype;
$attrClass = AttributeBase::getMatchingClass($datatype);
$attrClass::fromImport($row[$column]);
} catch(Exception $e) {
array_push($errors, $column);
array_push($errors, ["column" => $column, "value" => $row[$column]]);
}
}

if(count($errors) > 0) {
$this->rowConflict($index, "entity-importer.attribute-could-not-be-imported", ["attribute" => implode(", ", $errors)]);
$errorStrings = array_map(function ($error) {
return "{{" . $error['column'] . "}}" . " => " . "{{" . $error['value'] . "}}";
}, $errors);
$this->rowConflict($index, "entity-importer.attribute-could-not-be-imported", ["attributeErrors" => implode(", ", $errorStrings)]);
}
return count($errors) == 0;
}
Expand Down
61 changes: 61 additions & 0 deletions database/migrations/2024_12_02_132705_move_entity_type_color.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

use App\AvailableLayer;
use App\EntityType;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
activity()->disableLogging();

Schema::table('entity_types', function (Blueprint $table) {
$table->text('color')->nullable();
});

// migrate existing colors from map plugin table
if(Schema::hasTable('available_layers')) {
$entityTypeLayers = AvailableLayer::has('entity_type')->get();

foreach($entityTypeLayers as $entityTypeLayer) {
$color = $entityTypeLayer->color;
$entityTypeLayer->color = null;
$entityTypeLayer->saveQuietly();
$entityType = EntityType::find($entityTypeLayer->entity_type_id);
$entityType->color = $color;
$entityType->saveQuietly();
}
}

activity()->enableLogging();
}

/**
* Reverse the migrations.
*/
public function down(): void
{
activity()->disableLogging();

if(Schema::hasTable('available_layers')) {
$entityTypeLayers = AvailableLayer::has('entity_type')->get();

foreach($entityTypeLayers as $entityTypeLayer) {
$entityTypeLayer->color = $entityTypeLayer->entity_type->color;
$entityTypeLayer->saveQuietly();
}
}

Schema::table('entity_types', function (Blueprint $table) {
$table->dropColumn('color');
});

activity()->enableLogging();
}
};
10 changes: 10 additions & 0 deletions database/seeders/Demo/EntityAttributesTableSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,16 @@ public function run()
'position' => 6,
'depends_on' => NULL,
),
23 =>
array (
'id' => 26,
'entity_type_id' => 3, // Fundstelle
'attribute_id' => 19, // Aufbewahrung [string]
'created_at' => '2017-12-20 17:00:43',
'updated_at' => '2017-12-20 17:01:58',
'position' => 3,
'depends_on' => NULL,
),
));
}
}
5 changes: 5 additions & 0 deletions database/seeders/Demo/EntityTypesTableSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function run()
'created_at' => '2017-12-20 10:03:06',
'updated_at' => '2017-12-20 10:03:06',
'is_root' => true,
'color' => '#FF0000',
),
1 =>
array (
Expand All @@ -30,6 +31,7 @@ public function run()
'created_at' => '2017-12-20 10:03:15',
'updated_at' => '2017-12-20 10:03:15',
'is_root' => false,
'color' => '#FFFF00',
),
2 =>
array (
Expand All @@ -38,6 +40,7 @@ public function run()
'created_at' => '2017-12-20 10:03:23',
'updated_at' => '2017-12-20 10:03:23',
'is_root' => false,
'color' => '#00FF00',
),
3 =>
array (
Expand All @@ -46,6 +49,7 @@ public function run()
'created_at' => '2017-12-20 10:03:30',
'updated_at' => '2017-12-20 10:03:30',
'is_root' => false,
'color' => '#00FFFF',
),
4 =>
array (
Expand All @@ -54,6 +58,7 @@ public function run()
'created_at' => '2017-12-20 16:57:41',
'updated_at' => '2017-12-20 16:57:41',
'is_root' => true,
'color' => '#0000FF',
),
));
}
Expand Down
4 changes: 3 additions & 1 deletion lang/de/entity-importer.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<?php

return [
Expand All @@ -7,6 +6,9 @@
'missing-data' => 'Benötigte Spalte fehlt: :column',
'invalid-data' => 'Ungültige Daten: [:column] => :value',
'csv-column-mismatch' => 'Die Anzahl der Spalten in der aktuellen Zeile \':data\' (:data_count Spalten) stimmt nicht mit den Spalten der Kopfzeile \':header_data\' (:header_count Spalten) überein.',
'attribute-could-not-be-imported' => 'Attribut konnte nicht importiert werden: :attributeErrors',
'attribute-id-does-not-exist' => 'Die Attribut-ID existiert nicht: :attributes',
'attribute-column-does-not-exist' => 'Die Attribut-Spalten existieren nicht: :columns',
'name-column-does-not-exist' => 'Die Spalte für den Namen existiert nicht: :column',
'parent-column-does-non-exist' => 'Die Spalte für die Eltern-Entität existiert nicht: :column',
'parent-entity-does-not-exist' => 'Die Eltern-Entität existiert nicht: :entity',
Expand Down
1 change: 1 addition & 0 deletions lang/en/entity-importer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
'invalid-data' => 'Invalid data: [:column] => :value',
'csv-column-mismatch' => 'Column count of current row \':data\' (:data_count columns) does not match column count in header row \':header_data\' (:header_count columns).',
'attribute-could-not-be-imported' => 'Attribute could not be imported: :attribute',
'attribute-could-not-be-imported' => 'Attribute could not be imported: :attributeErrors',
'attribute-id-does-not-exist' => 'The attribute id does not exist: :attributes',
'attribute-column-does-not-exist' => 'The attribute columns do not exist: :columns',
'name-column-does-not-exist' => 'The column for the name does not exist: :column',
Expand Down
2 changes: 1 addition & 1 deletion resources/js/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ export async function confirmUserPassword(uid, password = null) {
}

export async function updateEntityTypeRelation(etid, values) {
const data = only(values, ['is_root', 'sub_entity_types']);
const data = only(values, ['is_root', 'sub_entity_types', 'color']);
const apiData = { ...data };
if(data.sub_entity_types) {
apiData.sub_entity_types = data.sub_entity_types.map(t => t.id);
Expand Down
11 changes: 8 additions & 3 deletions resources/js/bootstrap/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@/helpers/tree.js';
import {
can,
calculateEntityColors,
fillEntityData,
only,
slugify,
Expand Down Expand Up @@ -159,10 +160,14 @@ export const store = createStore({
},
updateEntityType(state, data) {
const entityType = state.entityTypes[data.id];
const values = only(data, ['thesaurus_url', 'updated_at', 'is_root', 'sub_entity_types']);
const values = only(data, ['thesaurus_url', 'updated_at', 'is_root', 'sub_entity_types', 'color']);
for(let k in values) {
entityType[k] = values[k];
}
if(data.color) {
const colors = calculateEntityColors(data.id);
state.entityTypeColors[data.id] = colors;
}
},
moveEntity(state, data) {
const entity = state.entities[data.entity_id];
Expand Down Expand Up @@ -282,8 +287,8 @@ export const store = createStore({
}
}

// Remove the data from the entity.
// We need to do this as the 'replace', 'add' 'remove'
// Remove the data from the entity.
// We need to do this as the 'replace', 'add' 'remove'
// operations are calculated based on this value.
for(const attributeId in data.removed_data) {
if(entity.data[attributeId]) {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/AttributeList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@
};
const certainty = attribute => {
return state.attributeValues?.[attribute.id]?.certainty;
return state.attributeValues?.[attribute.id]?.certainty ?? null;
};
const hasComment = attribute => {
Expand Down
Loading

0 comments on commit c4b598f

Please sign in to comment.