From 3b61d5823905d03410b245798e2ed5e2e0371c4e Mon Sep 17 00:00:00 2001 From: William Allen <16820599+williamjallen@users.noreply.github.com> Date: Tue, 4 Feb 2025 10:48:32 -0500 Subject: [PATCH] Edit site description directly from `/sites/` --- .../Mutations/UpdateSiteDescription.php | 43 +++ app/Http/Controllers/SiteController.php | 273 ------------------ app/Models/SiteInformation.php | 3 +- app/cdash/public/editSite.xsl | 227 --------------- app/cdash/tests/CMakeLists.txt | 4 + graphql/schema.graphql | 18 ++ phpstan-baseline.neon | 199 +------------ resources/js/vue/components/SitesIdPage.vue | 239 ++++++++++++--- resources/js/vue/components/UserHomepage.vue | 4 +- routes/web.php | 14 +- tests/Browser/Pages/SitesIdPageTest.php | 82 ++++++ .../Mutations/UpdateSiteDescriptionTest.php | 150 ++++++++++ 12 files changed, 514 insertions(+), 742 deletions(-) create mode 100644 app/GraphQL/Mutations/UpdateSiteDescription.php delete mode 100644 app/cdash/public/editSite.xsl create mode 100644 tests/Feature/GraphQL/Mutations/UpdateSiteDescriptionTest.php diff --git a/app/GraphQL/Mutations/UpdateSiteDescription.php b/app/GraphQL/Mutations/UpdateSiteDescription.php new file mode 100644 index 0000000000..ec02f4d45a --- /dev/null +++ b/app/GraphQL/Mutations/UpdateSiteDescription.php @@ -0,0 +1,43 @@ +user(); + + if ($user === null) { + abort(401, 'Authentication required to edit site descriptions.'); + } + + $site = Site::find((int) $args['siteId']); + + if ($site === null) { + abort(404, 'Requested site not found.'); + } + + $newSiteInformation = $site->mostRecentInformation?->getAttributes() ?? []; + unset($newSiteInformation['id']); + unset($newSiteInformation['siteid']); + unset($newSiteInformation['timestamp']); + $newSiteInformation['description'] = $args['description']; + $site->information()->create($newSiteInformation); + + $this->site = $site; + } +} diff --git a/app/Http/Controllers/SiteController.php b/app/Http/Controllers/SiteController.php index 2d112c291c..aa6ff05f33 100644 --- a/app/Http/Controllers/SiteController.php +++ b/app/Http/Controllers/SiteController.php @@ -3,11 +3,7 @@ namespace App\Http\Controllers; use App\Models\Site; -use App\Models\User; -use CDash\Database; -use CDash\Model\Project; use Illuminate\Http\RedirectResponse; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\View\View; @@ -96,278 +92,9 @@ public function siteStatistics(): View|RedirectResponse ->with('sites', $sites); } - public function editSite(): View|RedirectResponse - { - $userid = Auth::id(); - - $xml = begin_XML_for_XSLT(); - $xml .= 'CDash'; - $xml .= 'Claim sites'; - - // Post - @$claimsites = $_POST['claimsites']; - $availablesites = $_POST['availablesites'] ?? []; - $checkedsites = $_POST['checkedsites'] ?? []; - if ($claimsites) { - foreach ($availablesites as $siteid) { - if (array_key_exists($siteid, $checkedsites)) { - self::add_site2user(intval($siteid), intval($userid)); - } else { - self::remove_site2user(intval($siteid), intval($userid)); - } - } - $xml .= add_XML_value('warning', 'Claimed sites updated.'); - } - - @$claimsite = $_POST['claimsite']; - $claimsiteid = intval($_POST['claimsiteid'] ?? -1); - if ($claimsite) { - self::add_site2user(intval($claimsiteid), intval($userid)); - } - - @$updatesite = $_POST['updatesite']; - @$geolocation = $_POST['geolocation']; - - $db = Database::getInstance(); - - if (isset($_POST['unclaimsite']) && isset($_GET['siteid'])) { - DB::delete(' - DELETE FROM site2user - WHERE siteid=? AND userid=? - ', [intval($_GET['siteid']), $userid]); - return redirect('/user'); - } - - if ($updatesite || $geolocation) { - $site_name = request()->string('site_name'); - $site_description = request()->post('site_description'); - $site_processoris64bits = request()->post('site_processoris64bits'); - $site_processorvendor = request()->post('site_processorvendor'); - $site_processorvendorid = request()->post('site_processorvendorid'); - $site_processorfamilyid = request()->post('site_processorfamilyid'); - $site_processormodelid = request()->post('site_processormodelid'); - $site_processorcachesize = request()->post('site_processorcachesize'); - $site_numberlogicalcpus = request()->post('site_numberlogicalcpus'); - $site_numberphysicalcpus = request()->post('site_numberphysicalcpus'); - $site_totalvirtualmemory = request()->post('site_totalvirtualmemory'); - $site_totalphysicalmemory = request()->post('site_totalphysicalmemory'); - $site_logicalprocessorsperphysical = request()->post('site_logicalprocessorsperphysical'); - $site_processorclockfrequency = request()->post('site_processorclockfrequency'); - $site_ip = $_POST['site_ip']; - $site_longitude = $_POST['site_longitude']; - $site_latitude = $_POST['site_latitude']; - - if (isset($_POST['outoforder'])) { - $outoforder = true; - } else { - $outoforder = false; - } - } - - if ($updatesite) { - self::update_site( - $claimsiteid, - $site_name, - [ - 'processoris64bits' => $site_processoris64bits, - 'processorvendor' => $site_processorvendor, - 'processorvendorid' => $site_processorvendorid, - 'processorfamilyid' => $site_processorfamilyid, - 'processormodelid' => $site_processormodelid, - 'processorcachesize' => $site_processorcachesize, - 'numberlogicalcpus' => $site_numberlogicalcpus, - 'numberphysicalcpus' => $site_numberphysicalcpus, - 'totalvirtualmemory' => $site_totalvirtualmemory, - 'totalphysicalmemory' => $site_totalphysicalmemory, - 'logicalprocessorsperphysical' => $site_logicalprocessorsperphysical, - 'processorclockfrequency' => $site_processorclockfrequency, - 'description' => $site_description, - ], - $site_ip, - $site_latitude, - $site_longitude, - $outoforder - ); - } - - // If we should retrieve the geolocation - if ($geolocation) { - $location = get_geolocation($site_ip); - self::update_site( - $claimsiteid, - $site_name, - [ - 'processoris64bits' => $site_processoris64bits, - 'processorvendor' => $site_processorvendor, - 'processorvendorid' => $site_processorvendorid, - 'processorfamilyid' => $site_processorfamilyid, - 'processormodelid' => $site_processormodelid, - 'processorcachesize' => $site_processorcachesize, - 'numberlogicalcpus' => $site_numberlogicalcpus, - 'numberphysicalcpus' => $site_numberphysicalcpus, - 'totalvirtualmemory' => $site_totalvirtualmemory, - 'totalphysicalmemory' => $site_totalphysicalmemory, - 'logicalprocessorsperphysical' => $site_logicalprocessorsperphysical, - 'processorclockfrequency' => $site_processorclockfrequency, - 'description' => $site_description, - ], - $site_ip, - $location['latitude'], - $location['longitude'], - $outoforder - ); - } - - // If we have a projectid that means we should list all the sites - $projectid = $_GET['projectid'] ?? null; - if ($projectid !== null) { - $projectid = (int) $projectid; - } - if ($projectid !== null) { - $project_array = $db->executePreparedSingleRow('SELECT name FROM project WHERE id=?', [$projectid]); - $xml .= ''; - $xml .= add_XML_value('id', $projectid); - $xml .= add_XML_value('name', $project_array['name']); - $xml .= ''; - - // Select sites that belong to this project - $beginUTCTime = gmdate(FMT_DATETIME, time() - 3600 * 7 * 24); // 7 days - $site2project = $db->executePrepared(' - SELECT DISTINCT site.id, site.name - FROM build, site - WHERE - build.projectid=? - AND build.starttime>? - AND site.id=build.siteid - ORDER BY site.name ASC - ', [$projectid, $beginUTCTime]); - - foreach ($site2project as $site2project_array) { - $siteid = intval($site2project_array['id']); - $xml .= ''; - $xml .= add_XML_value('id', $siteid); - $xml .= add_XML_value('name', $site2project_array['name']); - $user2site = $db->executePreparedSingleRow(' - SELECT COUNT(*) AS c - FROM site2user - WHERE siteid=? AND userid=? - ', [$siteid, intval($userid)]); - if (intval($user2site['c']) === 0) { - $xml .= add_XML_value('claimed', '0'); - } else { - $xml .= add_XML_value('claimed', '1'); - } - $xml .= ''; - } - } - - // If we have a siteid we look if the user has claimed the site or not - $siteid = $_GET['siteid'] ?? null; - if ($siteid !== null) { - $xml .= ''; - $xml .= ''; - $site = Site::findOrFail((int) $siteid); - - $xml .= add_XML_value('id', $site->id); - $xml .= add_XML_value('name', $site->name); - $xml .= add_XML_value('description', stripslashes($site->mostRecentInformation->description ?? '')); - $xml .= add_XML_value('processoris64bits', $site->mostRecentInformation?->processoris64bits); - $xml .= add_XML_value('processorvendor', $site->mostRecentInformation?->processorvendor); - $xml .= add_XML_value('processorvendorid', $site->mostRecentInformation?->processorvendorid); - $xml .= add_XML_value('processorfamilyid', $site->mostRecentInformation?->processorfamilyid); - $xml .= add_XML_value('processormodelid', $site->mostRecentInformation?->processormodelid); - $xml .= add_XML_value('processorcachesize', $site->mostRecentInformation?->processorcachesize); - $xml .= add_XML_value('numberlogicalcpus', $site->mostRecentInformation?->numberlogicalcpus); - $xml .= add_XML_value('numberphysicalcpus', $site->mostRecentInformation?->numberphysicalcpus); - $xml .= add_XML_value('totalvirtualmemory', $site->mostRecentInformation?->totalvirtualmemory); - $xml .= add_XML_value('totalphysicalmemory', $site->mostRecentInformation?->totalphysicalmemory); - $xml .= add_XML_value('logicalprocessorsperphysical', $site->mostRecentInformation?->logicalprocessorsperphysical); - $xml .= add_XML_value('processorclockfrequency', $site->mostRecentInformation?->processorclockfrequency); - $xml .= add_XML_value('ip', $site->ip); - $xml .= add_XML_value('latitude', $site->latitude); - $xml .= add_XML_value('longitude', $site->longitude); - $xml .= add_XML_value('outoforder', $site->outoforder); - $xml .= ''; - - $user2site = $db->executePreparedSingleRow(' - SELECT su.userid - FROM - site2user AS su, - user2project AS up - WHERE - su.userid=up.userid - AND up.role>0 - AND su.siteid=? - AND su.userid=? - ', [$siteid, $userid]); - echo pdo_error(); - if (!empty($user2site)) { - $xml .= add_XML_value('siteclaimed', '0'); - } else { - $xml .= add_XML_value('siteclaimed', '1'); - } - - $xml .= ''; - } - - $xml .= ''; - - return $this->view('cdash', 'Edit Site') - ->with('xsl', true) - ->with('xsl_content', generate_XSLT($xml, base_path() . '/app/cdash/public/editSite', true)); - } - public function viewSite(Site $site): View { return $this->view('site.view-site', $site->name) ->with('site', $site); } - - /** - * add a user to a site - */ - private static function add_site2user(int $siteid, int $userid): void - { - $db = Database::getInstance(); - $site2user = $db->executePrepared('SELECT * FROM site2user WHERE siteid=? AND userid=?', [intval($siteid), intval($userid)]); - if (!empty($site2user)) { - DB::insert('INSERT INTO site2user (siteid, userid) VALUES (?, ?)', [$siteid, $userid]); - } - } - - /** - * remove a user from a site - */ - private static function remove_site2user(int $siteid, int $userid): void - { - DB::delete('DELETE FROM site2user WHERE siteid=? AND userid=?', [$siteid, $userid]); - } - - /** - * Update a site - * - * @param array $information - */ - private static function update_site( - int $siteid, - string $name, - array $information, - $ip, - $latitude, - $longitude, - bool $outoforder = false, - ): void { - // Update the basic information first - $site = Site::findOrFail($siteid); - $site->updateOrFail([ - 'name' => $name, - 'ip' => $ip, - 'latitude' => $latitude, - 'longitude' => $longitude, - 'outoforder' => $outoforder, - ]); - - // Create a new information row if something has changed since the most recent update - $site->mostRecentInformation()->firstOrCreate($information); - } } diff --git a/app/Models/SiteInformation.php b/app/Models/SiteInformation.php index 935f12f961..fb0cd054f1 100644 --- a/app/Models/SiteInformation.php +++ b/app/Models/SiteInformation.php @@ -5,9 +5,10 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Support\Carbon; /** - * @property string $timestamp + * @property Carbon $timestamp * @property bool|null $processoris64bits * @property string|null $processorvendor * @property string|null $processorvendorid diff --git a/app/cdash/public/editSite.xsl b/app/cdash/public/editSite.xsl deleted file mode 100644 index 89e2a59875..0000000000 --- a/app/cdash/public/editSite.xsl +++ /dev/null @@ -1,227 +0,0 @@ - - - - - -
-
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
List of current sites for
- checkedsites[] - - - - - - - - -
- -
-
-
-
- - - -
- - - - - - - - - - - - - - - - - -
Would you like to claim as a site you are managing?
- - -
-
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Site specifications for
Name: - - - (Make sure the name of the build matches CTest buildname otherwise a new site will be created) -
64 bits: - - -
Processor vendor: - - -
Processor vendor ID: - - -
Processor family ID: - - -
Processor model ID: - - -
Processor cache size: - - -
CPU Speed (MHz): - - -
Number of logical CPUs: - - -
Number of physical CPUs: - - -
Logical Processor per Physical: - - -
Total virtual memory (MB): - - -
Total physical memory (MB): - - -
Description: - - -
IP address: - - - -
Latitude: - - -
Longitude: - - -
Force new description revision: - - (check this box only if the system has been upgraded, i.e memory upgrade,...) -
Mark site as temporary out of order: - - - - - -
- - - -
-
-
-
-
diff --git a/app/cdash/tests/CMakeLists.txt b/app/cdash/tests/CMakeLists.txt index 19950c2fe6..7455a7bb88 100644 --- a/app/cdash/tests/CMakeLists.txt +++ b/app/cdash/tests/CMakeLists.txt @@ -275,6 +275,9 @@ set_tests_properties(/Feature/Mail/AuthTokenExpiringTest PROPERTIES DEPENDS /CDa add_laravel_test(/Feature/Mail/AuthTokenExpiredTest) set_tests_properties(/Feature/Mail/AuthTokenExpiredTest PROPERTIES DEPENDS /CDash/XmlHandler/UpdateHandler) +add_laravel_test(/Feature/GraphQL/Mutations/UpdateSiteDescriptionTest) +set_tests_properties(/Feature/GraphQL/Mutations/UpdateSiteDescriptionTest PROPERTIES DEPENDS /CDash/XmlHandler/UpdateHandler) + ################################################################################################### cdash_install() @@ -313,6 +316,7 @@ set_property(TEST install_3 PROPERTY DEPENDS /Feature/Jobs/NotifyExpiringAuthTokensTest /Feature/Mail/AuthTokenExpiringTest /Feature/Mail/AuthTokenExpiredTest + /Feature/GraphQL/Mutations/UpdateSiteDescriptionTest ) diff --git a/graphql/schema.graphql b/graphql/schema.graphql index 635de14483..fddd42b62b 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -49,6 +49,9 @@ type Mutation { "Unsubscribe the current user from the specified site." unclaimSite(input: UnclaimSiteInput! @spread): UnclaimSiteMutationPayload! @field(resolver: "UnclaimSite") + + "Edit the site description." + updateSiteDescription(input: UpdateSiteDescriptionInput! @spread): UpdateSiteDescriptionMutationPayload! @field(resolver: "UpdateSiteDescription") } @@ -497,9 +500,24 @@ input UnclaimSiteInput { siteId: ID! } +input UpdateSiteDescriptionInput { + siteId: ID! + description: String! +} + +type UpdateSiteDescriptionMutationPayload implements MutationPayloadInterface { + "Optional error message." + message: String + + site: Site +} + "Details about a site at a given point in time." type SiteInformation { + "Unique primary key." + id: ID! + "Creation timestamp." timestamp: DateTimeTz! diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a8799cfd1e..cc4d1a9be6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -261,6 +261,16 @@ parameters: count: 1 path: app/GraphQL/Mutations/UnclaimSite.php + - + message: "#^Dynamic call to static method Illuminate\\\\Contracts\\\\Auth\\\\Guard\\:\\:user\\(\\)\\.$#" + count: 1 + path: app/GraphQL/Mutations/UpdateSiteDescription.php + + - + message: "#^Parameter \\#1 \\$args \\(array\\{siteId\\: int, description\\: string\\}\\) of method App\\\\GraphQL\\\\Mutations\\\\UpdateSiteDescription\\:\\:mutate\\(\\) should be contravariant with parameter \\$args \\(array\\\\) of method App\\\\GraphQL\\\\Mutations\\\\AbstractMutation\\:\\:mutate\\(\\)$#" + count: 1 + path: app/GraphQL/Mutations/UpdateSiteDescription.php + - message: "#^Cannot cast mixed to float\\.$#" count: 1 @@ -2435,200 +2445,11 @@ parameters: count: 1 path: app/Http/Controllers/RemoteProcessingController.php - - - message: "#^Argument of an invalid type array\\|false supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: """ - #^Call to deprecated function pdo_error\\(\\)\\: - 04/01/2023$# - """ - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: """ - #^Call to deprecated method executePrepared\\(\\) of class CDash\\\\Database\\: - 04/22/2023 Use Laravel query builder or Eloquent instead$# - """ - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: """ - #^Call to deprecated method executePreparedSingleRow\\(\\) of class CDash\\\\Database\\: - 04/22/2023 Use Laravel query builder or Eloquent instead$# - """ - count: 3 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Cannot access offset 'c' on array\\|false\\|null\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Cannot access offset 'name' on array\\|false\\|null\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Cannot cast mixed to int\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - message: "#^Method App\\\\Http\\\\Controllers\\\\SiteController\\:\\:siteStatistics\\(\\) never returns Illuminate\\\\Http\\\\RedirectResponse so it can be removed from the return type\\.$#" count: 1 path: app/Http/Controllers/SiteController.php - - - message: "#^Method App\\\\Http\\\\Controllers\\\\SiteController\\:\\:update_site\\(\\) has parameter \\$ip with no type specified\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Method App\\\\Http\\\\Controllers\\\\SiteController\\:\\:update_site\\(\\) has parameter \\$latitude with no type specified\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Method App\\\\Http\\\\Controllers\\\\SiteController\\:\\:update_site\\(\\) has parameter \\$longitude with no type specified\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Only booleans are allowed in an if condition, mixed given\\.$#" - count: 4 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Only booleans are allowed in \\|\\|, mixed given on the left side\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Only booleans are allowed in \\|\\|, mixed given on the right side\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Parameter \\#1 \\$key of function array_key_exists expects int\\|string, mixed given\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Parameter \\#1 \\$value of function intval expects array\\|bool\\|float\\|int\\|resource\\|string\\|null, mixed given\\.$#" - count: 4 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$outoforder might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_description might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_ip might not be defined\\.$#" - count: 3 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_latitude might not be defined\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_logicalprocessorsperphysical might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_longitude might not be defined\\.$#" - count: 1 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_name might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_numberlogicalcpus might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_numberphysicalcpus might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_processorcachesize might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_processorclockfrequency might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_processorfamilyid might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_processoris64bits might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_processormodelid might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_processorvendor might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_processorvendorid might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_totalphysicalmemory might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - - - message: "#^Variable \\$site_totalvirtualmemory might not be defined\\.$#" - count: 2 - path: app/Http/Controllers/SiteController.php - - message: "#^Access to an undefined property App\\\\Models\\\\Banner\\|Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\:\\:\\$text\\.$#" count: 1 diff --git a/resources/js/vue/components/SitesIdPage.vue b/resources/js/vue/components/SitesIdPage.vue index d70230b1f5..db1e6f7ae0 100644 --- a/resources/js/vue/components/SitesIdPage.vue +++ b/resources/js/vue/components/SitesIdPage.vue @@ -23,7 +23,7 @@ data-test="site-details-table" > - + {{ humanReadableSiteFieldName(field) }} -
-
- Description +
+
+
+ Description +
+
+ + +
-
- {{ mostRecentInformation.description }} +
+