Skip to content

Commit b4f98cc

Browse files
committed
use new parentAndChildDetails property on an image response, to add extra sections (with thumbnails) in the bottom left of the sidebar (below crops etc.)
1 parent a7d7d50 commit b4f98cc

File tree

6 files changed

+54
-8
lines changed

6 files changed

+54
-8
lines changed

kahuna/public/js/image/controller.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ image.controller('ImageCtrl', [
169169
ctrl.canUserEdit = editable;
170170
});
171171

172+
ctrl.objectHasEntries = obj => obj && Object.keys(obj).length > 0;
173+
172174
const usages = imageUsagesService.getUsages(ctrl.image);
173175
const usagesCount$ = usages.count$;
174176

kahuna/public/js/image/view.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,32 @@
151151
class="image-details__delete-crops"
152152
gr-image="ctrl.image"
153153
gr-on-delete="ctrl.onCropsDeleted()"></gr-delete-crops>
154+
155+
<div class="image-info image-details--scroll" style="margin-top: auto; max-height: 50%">
156+
<div ng-repeat="(title, idToDetailMap) in ctrl.image.data.parentAndChildDetails">
157+
<div class="image-info__group image-info__group--bottom" aria-label="{{title}}"
158+
ng-if="ctrl.objectHasEntries(idToDetailMap)">
159+
<dl class="image-info__group--dl">
160+
<dt class="image-info__heading">{{title}}</dt>
161+
<dd class="image-info__heading--crops"
162+
ng-repeat="(id, detail) in idToDetailMap">
163+
<a class="image-crop"
164+
ui-sref="image({imageId: id})"
165+
aria-label="View {{title}}">
166+
<img class="image-crop__image"
167+
alt="{{title}} {{id}} thumbnail"
168+
ng-src="{{detail.thumbnail}}" />
169+
<div class="flex-container image-crop__more-info">
170+
<span ng-if="detail.dimensions">{{detail.dimensions.width}} &times; {{detail.dimensions.height}}</span>
171+
<span class="flex-spacer"></span>
172+
<span class="image-crop__creator" title="Added by {{detail.addedBy}} at {{detail.addedAt | date:'medium'}}">{{detail.addedBy | getInitials}}</span>
173+
</div>
174+
</a>
175+
</dd>
176+
</dl>
177+
</div>
178+
</div>
179+
</div>
154180
</div>
155181

156182
<div class="image-details image-details--full-image" role="complementary" aria-label="Image information">

kahuna/public/stylesheets/main.css

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2102,7 +2102,8 @@ FIXME: what to do with touch devices
21022102
}
21032103

21042104
.image-details__delete-crops {
2105-
width: 100%;
2105+
width: 100%;
2106+
outline: 1px solid #565656;
21062107
}
21072108

21082109
.image-details:after {
@@ -2122,6 +2123,11 @@ FIXME: what to do with touch devices
21222123
border-bottom: 1px solid #565656;
21232124
}
21242125

2126+
.image-info__group--bottom {
2127+
border-bottom: 0;
2128+
border-top: 1px solid #565656;
2129+
}
2130+
21252131
.image-info__group--last {
21262132
border-bottom: 0;
21272133
clear: both;

media-api/app/controllers/MediaApi.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,8 @@ class MediaApi(
575575
val deleteImagePermission = authorisation.isUploaderOrHasPermission(request.user, source.instance.uploadedBy, DeleteImagePermission)
576576
val deleteCropsOrUsagePermission = canUserDeleteCropsOrUsages(request.user)
577577

578+
import JodaWrites._
579+
implicit val jsonDetailsWrites: OWrites[RelationDetail] = Json.writes[RelationDetail]
578580
val getRelationDetails = elasticSearch.getRelationDetails(id, imageResponse.getSecureThumbUrl)_
579581
val relationDetails = Map(
580582
"Replacement for" -> source.instance.identifiers.get(ImageStorageProps.replacesMediaIdIdentifierKey).map(getRelationDetails),

media-api/app/lib/elasticsearch/ElasticSearch.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.gu.mediaservice.lib.auth.Authentication.Principal
77
import com.gu.mediaservice.lib.elasticsearch.{CompletionPreview, ElasticSearchClient, ElasticSearchConfig, MigrationStatusProvider, Running}
88
import com.gu.mediaservice.lib.logging.{GridLogging, LogMarker, MarkerMap}
99
import com.gu.mediaservice.lib.metrics.FutureSyntax
10-
import com.gu.mediaservice.model.{Agencies, Agency, AwaitingReviewForSyndication, Image}
10+
import com.gu.mediaservice.model.{Agencies, Agency, AwaitingReviewForSyndication, Dimensions, Image}
1111
import com.sksamuel.elastic4s.ElasticDsl
1212
import com.sksamuel.elastic4s.ElasticDsl._
1313
import com.sksamuel.elastic4s.requests.get.{GetRequest, GetResponse}
@@ -282,12 +282,16 @@ class ElasticSearch(
282282

283283
def getRelationDetails(mediaIdThisIsFor: String, getSecureThumbUrl: Image => String)(
284284
id: String
285-
)(implicit ex: ExecutionContext, request: AuthenticatedRequest[AnyContent, Principal], logMarker:MarkerMap = MarkerMap()): (String, Option[Map[String, String]]) = {
285+
)(implicit ex: ExecutionContext, request: AuthenticatedRequest[AnyContent, Principal], logMarker:MarkerMap = MarkerMap()): (String, Option[RelationDetail]) = {
286286
try {
287-
id -> Await.result(getImageById(id), 5.seconds).map(image => Map(
288-
"thumbnail" -> getSecureThumbUrl(image),
289-
"addedBy" -> image.uploadedBy
290-
))
287+
id -> Await.result(getImageById(id), 5.seconds).map{image =>
288+
RelationDetail(
289+
thumbnail = getSecureThumbUrl(image),
290+
addedBy = image.uploadedBy,
291+
addedAt = image.uploadTime,
292+
dimensions = image.source.orientedDimensions.orElse(image.source.dimensions)
293+
)
294+
}
291295
} catch {
292296
case e: TimeoutException =>
293297
logger.error(logMarker, s"Timeout getting image $id (when finding relation details for $mediaIdThisIsFor)", e)

media-api/app/lib/elasticsearch/ElasticSearchModel.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package lib.elasticsearch
33
import com.gu.mediaservice.lib.auth.{Authentication, Tier}
44
import com.gu.mediaservice.lib.formatting.{parseDateFromQuery, printDateTime}
55
import com.gu.mediaservice.model.usage.UsageStatus
6-
import com.gu.mediaservice.model.{Image, PrintUsageFilters, SyndicationStatus}
6+
import com.gu.mediaservice.model.{Dimensions, Image, PrintUsageFilters, SyndicationStatus}
77
import lib.querysyntax.{Condition, Parser}
88
import org.joda.time.DateTime
99
import play.api.libs.json.{Json, OWrites}
@@ -54,6 +54,12 @@ object AggregateSearchParams {
5454
)
5555
}
5656
}
57+
case class RelationDetail(
58+
thumbnail: String,
59+
addedBy: String,
60+
addedAt: DateTime,
61+
dimensions: Option[Dimensions]
62+
)
5763

5864
case class SearchParams(
5965
query: Option[String] = None,

0 commit comments

Comments
 (0)