Skip to content

Commit 4e5f331

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 dae52e5 commit 4e5f331

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
@@ -2101,7 +2101,8 @@ FIXME: what to do with touch devices
21012101
}
21022102

21032103
.image-details__delete-crops {
2104-
width: 100%;
2104+
width: 100%;
2105+
outline: 1px solid #565656;
21052106
}
21062107

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

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

media-api/app/controllers/MediaApi.scala

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

499+
import JodaWrites._
500+
implicit val jsonDetailsWrites: OWrites[RelationDetail] = Json.writes[RelationDetail]
499501
val getRelationDetails = elasticSearch.getRelationDetails(id, imageResponse.getSecureThumbUrl)_
500502
val relationDetails = Map(
501503
"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, 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}
@@ -280,12 +280,16 @@ class ElasticSearch(
280280

281281
def getRelationDetails(mediaIdThisIsFor: String, getSecureThumbUrl: Image => String)(
282282
id: String
283-
)(implicit ex: ExecutionContext, request: AuthenticatedRequest[AnyContent, Principal], logMarker:MarkerMap = MarkerMap()): (String, Option[Map[String, String]]) = {
283+
)(implicit ex: ExecutionContext, request: AuthenticatedRequest[AnyContent, Principal], logMarker:MarkerMap = MarkerMap()): (String, Option[RelationDetail]) = {
284284
try {
285-
id -> Await.result(getImageById(id), 5.seconds).map(image => Map(
286-
"thumbnail" -> getSecureThumbUrl(image),
287-
"addedBy" -> image.uploadedBy
288-
))
285+
id -> Await.result(getImageById(id), 5.seconds).map{image =>
286+
RelationDetail(
287+
thumbnail = getSecureThumbUrl(image),
288+
addedBy = image.uploadedBy,
289+
addedAt = image.uploadTime,
290+
dimensions = image.source.orientedDimensions.orElse(image.source.dimensions)
291+
)
292+
}
289293
} catch {
290294
case e: TimeoutException =>
291295
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)