diff --git a/resources/build/admin.min.js b/resources/build/admin.min.js index 7b160f0..1cc4197 100644 --- a/resources/build/admin.min.js +++ b/resources/build/admin.min.js @@ -1 +1 @@ -$(document).ready(function(){var a=$("#faces-admin-config"),t=a.find("#faces-admin-config-table");function e(t){a.find(".alert").remove(),a.prepend(tmpl($("#faces-alert-template").html(),{message:t.message,readmore:t.link}))}t.dataTable({processing:!0,serverSide:!0,ajax:t.data("url"),autoWidth:!1,filter:!1,pageLength:10,pagingType:"full_numbers",stateSave:!0,cookieDuration:300,sort:!1,columns:[{className:"faces-td-photo text-break"},{className:"faces-td-notes"},{className:"faces-td-status"},{className:"faces-td-actions"}],fnDrawCallback:function(){t.find('[data-action="destroy"]').on("click",function(){confirm(window.WT_FACES_WARNING)&&$.ajax({url:$(this).data("url")}).done(function(a){e(a),t.DataTable().ajax.reload()})})}}),a.find('[data-action="setting-exif"], [data-action="setting-linking"], [data-action="setting-meta"]').on("change",function(a){$.ajax({url:$(this).data("url")}).done(function(a){e(a)})}),a.find('[aria-labelledby="faces-settings-menu"]').on("click",function(a){a.stopPropagation()}),a.find('[data-action="missed-repair"], [data-action="missed-delete"]').on("click",function(){confirm(window.WT_FACES_WARNING)&&$.ajax({url:$(this).data("url")}).done(function(a){e(a),t.DataTable().ajax.reload()})})}); +$(document).ready(function(){var a=$("#faces-admin-config"),t=a.find("#faces-admin-config-table");function n(t){a.find(".alert").remove(),a.prepend(tmpl($("#faces-alert-template").html(),{message:t.message,readmore:t.link}))}t.dataTable({processing:!0,serverSide:!0,ajax:t.data("url"),autoWidth:!1,filter:!1,pageLength:10,pagingType:"full_numbers",stateSave:!0,cookieDuration:300,sort:!1,columns:[{className:"faces-td-photo text-break"},{className:"faces-td-notes"},{className:"faces-td-status"},{className:"faces-td-actions"}],fnDrawCallback:function(){t.find('[data-action="destroy"]').on("click",function(){confirm(window.WT_FACES_WARNING)&&$.ajax({url:$(this).data("url")}).done(function(a){n(a),t.DataTable().ajax.reload()})})}}),a.find(['[data-action="setting-exif"]','[data-action="setting-linking"]','[data-action="setting-meta"]','[data-action="setting-tab"]'].join(", ")).on("change",function(){$.ajax({url:$(this).data("url")}).done(function(a){n(a)})}),a.find('[aria-labelledby="faces-settings-menu"]').on("click",function(a){a.stopPropagation()}),a.find(['[data-action="missed-repair"]','[data-action="missed-delete"]'].join(", ")).on("click",function(){confirm(window.WT_FACES_WARNING)&&$.ajax({url:$(this).data("url")}).done(function(a){n(a),t.DataTable().ajax.reload()})})}); diff --git a/resources/langs/en.php b/resources/langs/en.php index 455379a..0f3dd66 100644 --- a/resources/langs/en.php +++ b/resources/langs/en.php @@ -30,6 +30,8 @@ 'Link individual with media when mark them on photo' => 'Link individual with media when mark them on photo', 'Show meta' => 'Show meta', 'Load and show information from linked fact' => 'Load and show information from linked fact', + 'Show tab' => 'Show tab', + 'Show tab on individuals page' => 'Show tab on individuals page', //Config: Table //'Media' => 'Media', //'Notes' => 'Notes', diff --git a/resources/langs/ru.php b/resources/langs/ru.php index 0b8ec4d..c02903e 100644 --- a/resources/langs/ru.php +++ b/resources/langs/ru.php @@ -30,6 +30,8 @@ 'Link individual with media when mark them on photo' => 'Связывать персону с медиа при добавлении ее на фото', 'Show meta' => 'Показывать мету', 'Load and show information from linked fact' => 'Загружать и показывать информацию из связанного факта', + 'Show tab' => 'Показывать вкладку', + 'Show tab on individuals page' => 'Показывать вкладку на странице персоны', //Config: Table //'Media' => 'Медиа', //'Notes' => 'Примечания', diff --git a/resources/scripts/admin/config.js b/resources/scripts/admin/config.js index a4ec3ef..3401732 100644 --- a/resources/scripts/admin/config.js +++ b/resources/scripts/admin/config.js @@ -49,26 +49,40 @@ $(document).ready(function() { } }); - $page.find('[data-action="setting-exif"], [data-action="setting-linking"], [data-action="setting-meta"]').on('change', function(e) { - $.ajax({ - url: $(this).data('url') - }).done(function(response) { - facesShowMessage(response); - }); - }); - - $page.find('[aria-labelledby="faces-settings-menu"]').on('click', function(e) { - e.stopPropagation(); - }); - - $page.find('[data-action="missed-repair"], [data-action="missed-delete"]').on('click', function() { - if (confirm(window.WT_FACES_WARNING)) { + $page + .find([ + '[data-action="setting-exif"]', + '[data-action="setting-linking"]', + '[data-action="setting-meta"]', + '[data-action="setting-tab"]', + ].join(', ')) + .on('change', function() { $.ajax({ url: $(this).data('url') }).done(function(response) { facesShowMessage(response); - $table.DataTable().ajax.reload(); }); - } - }); + }); + + $page + .find('[aria-labelledby="faces-settings-menu"]') + .on('click', function(e) { + e.stopPropagation(); + }); + + $page + .find([ + '[data-action="missed-repair"]', + '[data-action="missed-delete"]', + ].join(', ')) + .on('click', function() { + if (confirm(window.WT_FACES_WARNING)) { + $.ajax({ + url: $(this).data('url') + }).done(function(response) { + facesShowMessage(response); + $table.DataTable().ajax.reload(); + }); + } + }); }); \ No newline at end of file diff --git a/resources/views/admin/config.phtml b/resources/views/admin/config.phtml index dfb3367..a9b03c1 100644 --- a/resources/views/admin/config.phtml +++ b/resources/views/admin/config.phtml @@ -83,6 +83,20 @@ use Fisharebest\Webtrees\View; + + + > + + + diff --git a/resources/views/tab.phtml b/resources/views/tab.phtml new file mode 100644 index 0000000..579a053 --- /dev/null +++ b/resources/views/tab.phtml @@ -0,0 +1,13 @@ +
+
+ + mediaFiles() as $file) : ?> +
+
+ displayImage(200, 200, 'contain', ['rel' => 'faces-tab', 'class' => 'card-img-top']) ?> +
+
+ + +
+
diff --git a/src/Helpers/DatabaseHelper.php b/src/Helpers/DatabaseHelper.php index 8624381..cf7f3d1 100644 --- a/src/Helpers/DatabaseHelper.php +++ b/src/Helpers/DatabaseHelper.php @@ -67,10 +67,20 @@ public function setMediaMap( return null; } - public function getMediaList(?string $media, ?string $person, ?string $search, int $start, int $length): array - { + public function getMediaList( + ?int $tree, + ?string $media, + ?string $person, + ?string $search, + int $start, + int $length + ): array { $query = DB::table('media_faces'); + if ($tree !== null) { + $query->where('f_m_tree', '=', $tree); + } + if ($media !== null) { $query->where('f_m_id', '=', $media); } diff --git a/src/Http/Controllers/AdminController.php b/src/Http/Controllers/AdminController.php index a9eb9f8..ca7e1ef 100644 --- a/src/Http/Controllers/AdminController.php +++ b/src/Http/Controllers/AdminController.php @@ -48,6 +48,8 @@ public function handle(ServerRequestInterface $request): Response return $this->settingLinking(); case 'setting_meta': return $this->settingMeta(); + case 'setting_tab': + return $this->settingTab(); case 'missed_repair': return $this->missedRepair(); case 'missed_destroy': @@ -70,6 +72,7 @@ private function config(Request $request): Response 'exif' => $this->module->settingEnabled(FacesModule::SETTING_EXIF_NAME), 'linking' => $this->module->settingEnabled(FacesModule::SETTING_LINKING_NAME), 'meta' => $this->module->settingEnabled(FacesModule::SETTING_META_NAME), + 'tab' => $this->module->settingEnabled(FacesModule::SETTING_TAB_NAME), ], 'filters' => array_filter([ $request->getQueryParams()['mid'] ?? null, @@ -93,6 +96,9 @@ private function config(Request $request): Response 'setting_meta' => route(self::ROUTE_PREFIX, [ 'action' => 'setting_meta', ]), + 'setting_tab' => route(self::ROUTE_PREFIX, [ + 'action' => 'setting_tab', + ]), 'missed_repair' => route(self::ROUTE_PREFIX, [ 'action' => 'missed_repair', ]), @@ -113,6 +119,7 @@ private function config(Request $request): Response private function data(Request $request): Response { [$rows, $total] = $this->module->query->getMediaList( + null, $request->getQueryParams()['mid'] ?? null, $request->getQueryParams()['pid'] ?? null, $request->getQueryParams()['q'] ?? null, @@ -231,7 +238,19 @@ private function settingMeta(): Response 'success' => true, 'message' => "{$state}: " . I18N::translate('Load and show information from linked fact') . '.', + ]); + } + + private function settingTab(): Response + { + $state = $this->module->settingToggle(FacesModule::SETTING_TAB_NAME) + ? I18N::translate('Enabled') + : I18N::translate('Disabled'); + return response([ + 'success' => true, + 'message' => "{$state}: " + . I18N::translate('Show tab on individuals page') . '.', ]); } diff --git a/src/Modules/FacesModule.php b/src/Modules/FacesModule.php index a6cf941..361deed 100644 --- a/src/Modules/FacesModule.php +++ b/src/Modules/FacesModule.php @@ -4,6 +4,8 @@ use Aura\Router\RouterContainer; use Fig\Http\Message\RequestMethodInterface; +use Fisharebest\Webtrees\Factory; +use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Module\AbstractModule; use Fisharebest\Webtrees\Module\ModuleConfigInterface; use Fisharebest\Webtrees\Module\ModuleConfigTrait; @@ -11,6 +13,8 @@ use Fisharebest\Webtrees\Module\ModuleCustomTrait; use Fisharebest\Webtrees\Module\ModuleGlobalInterface; use Fisharebest\Webtrees\Module\ModuleGlobalTrait; +use Fisharebest\Webtrees\Module\ModuleTabInterface; +use Fisharebest\Webtrees\Module\ModuleTabTrait; use Fisharebest\Webtrees\Services\MigrationService; use Fisharebest\Webtrees\Tree; use Fisharebest\Webtrees\View; @@ -23,11 +27,12 @@ use UksusoFF\WebtreesModules\Faces\Http\Controllers\DataController; use UksusoFF\WebtreesModules\Faces\Http\Controllers\MediaHelper; -class FacesModule extends AbstractModule implements ModuleCustomInterface, ModuleGlobalInterface, ModuleConfigInterface, MiddlewareInterface +class FacesModule extends AbstractModule implements ModuleCustomInterface, ModuleGlobalInterface, ModuleConfigInterface, ModuleTabInterface, MiddlewareInterface { use ModuleCustomTrait; use ModuleGlobalTrait; use ModuleConfigTrait; + use ModuleTabTrait; public const SCHEMA_VERSION = '6'; @@ -43,6 +48,8 @@ class FacesModule extends AbstractModule implements ModuleCustomInterface, Modul public const SETTING_META_NAME = 'FACES_META_ENABLED'; + public const SETTING_TAB_NAME = 'FACES_TAB_ENABLED'; + public $query; public $media; @@ -187,4 +194,54 @@ public function getConfigLink(): string 'action' => 'config', ]); } + + public function getTabContent(Individual $individual): string + { + if (!$this->settingEnabled(self::SETTING_TAB_NAME)) { + return ''; + } + + [$rows, $total] = $this->query->getMediaList( + $individual->tree()->id(), + null, + $individual->xref(), + null, + 0, + 1000 + ); + + return view("{$this->name()}::tab", [ + 'list' => $rows->map(function($row) use ($individual) { + return Factory::media()->make($row->f_m_id, $individual->tree()); + }), + ]); + } + + public function hasTabContent(Individual $individual): bool + { + if (!$this->settingEnabled(self::SETTING_TAB_NAME)) { + return false; + } + + [$rows, $total] = $this->query->getMediaList( + $individual->tree()->id(), + null, + $individual->xref(), + null, + 0, + 1 + ); + + return $total > 0; + } + + public function canLoadAjax(): bool + { + return true; + } + + public function isGrayedOut(Individual $individual): bool + { + return false; + } }