diff --git a/app/scripts/directives/catalog/catalogImage.js b/app/scripts/directives/catalog/catalogImage.js index 8d25f9ce30..84bafc3545 100644 --- a/app/scripts/directives/catalog/catalogImage.js +++ b/app/scripts/directives/catalog/catalogImage.js @@ -37,14 +37,19 @@ angular.module('openshiftConsole') return _.includes(tags, 'builder'); }; - var tags = _.get($scope, 'imageStream.status.tags', []); - $scope.tags = _.filter(tags, function(tag) { - return isBuilder(tag.tag) && !referenceTags[tag.tag]; - }); + // Watch status tags. Some tags might be removed from the list if they + // don't match the current filter. + $scope.$watch('imageStream.status.tags', function(tags) { + $scope.tags = _.filter(tags, function(tag) { + return isBuilder(tag.tag) && !referenceTags[tag.tag]; + }); - // Preselect the first tag value. - var firstTag = _.head($scope.tags); - _.set($scope, 'is.tag', firstTag); + var selected = _.get($scope, 'is.tag.tag'); + if (!selected || !_.some($scope.tags, { tag: selected })) { + // Preselect the first tag value. + _.set($scope, 'is.tag', _.head($scope.tags)); + } + }); } }; }); diff --git a/app/scripts/services/catalog.js b/app/scripts/services/catalog.js index 51a442e650..a2ecd4cbad 100644 --- a/app/scripts/services/catalog.js +++ b/app/scripts/services/catalog.js @@ -121,14 +121,68 @@ angular.module("openshiftConsole") return templatesByCategory; }; - // TODO: Filter by description - var imageStreamFilterFields = [ - 'metadata.name', - 'metadata.annotations["openshift.io/display-name"]' - ]; - + // Don't use KeywordService for image stream filtering so we can add + // special handling for image stream tags. Match keywords (array of regex) + // against image streams and image stream tags, returning a copy of the + // image streams with only matching status tags. + var getDisplayName = $filter('displayName'); var filterImageStreams = function(imageStreams, keywords) { - return KeywordService.filterForKeywords(imageStreams, imageStreamFilterFields, keywords); + if (!keywords.length) { + return imageStreams; + } + + var filteredImageStreams = []; + _.each(imageStreams, function(imageStream) { + var name = _.get(imageStream, 'metadata.name', ''); + var displayName = getDisplayName(imageStream, true); + var matchingTags = _.indexBy(imageStream.spec.tags, 'name'); + + // Find tags that match every keyword. Search image stream name, image + // stream display name, and tag names, and tag descriptions. If a + // keyword matches the image stream name or display name, it's + // considered to match all tags. + _.each(keywords, function(regex) { + if (regex.test(name)) { + return; + } + + if (displayName && regex.test(displayName)) { + return; + } + + // Check tag descriptions. + _.each(imageStream.spec.tags, function(tag) { + // If this is not a builder, don't match the tag. + var tagTags = _.get(tag, 'annotations.tags', ''); + if (!/\bbuilder\b/.test(tagTags)) { + delete matchingTags[tag.name]; + return; + } + + // If the keyword matches the tag name, accept it. + if (regex.test(tag.name)) { + return; + } + + var description = _.get(tag, 'annotations.description'); + if (!description || !regex.test(description)) { + delete matchingTags[tag.name]; + } + }); + }); + + // Make a copy of the image stream with only the matching tags. + var imageStreamCopy; + if (!_.isEmpty(matchingTags)) { + imageStreamCopy = angular.copy(imageStream); + imageStreamCopy.status.tags = _.filter(imageStreamCopy.status.tags, function(tag) { + return matchingTags[tag.tag]; + }); + filteredImageStreams.push(imageStreamCopy); + } + }); + + return filteredImageStreams; }; var templateFilterFields = [ diff --git a/dist/scripts/scripts.js b/dist/scripts/scripts.js index b17972ee9d..c5ac3bcf9e 100644 --- a/dist/scripts/scripts.js +++ b/dist/scripts/scripts.js @@ -3794,8 +3794,26 @@ _.each(e, function(d) { h(d, c) && (b[d.id] = b[d.id] || [], b[d.id].push(a), f = !0); }), f || (b[""] = b[""] || [], b[""].push(a)); }), b; -}, k = [ "metadata.name", 'metadata.annotations["openshift.io/display-name"]' ], l = function(a, b) { -return c.filterForKeywords(a, k, b); +}, k = a("displayName"), l = function(a, b) { +if (!b.length) return a; +var c = []; +return _.each(a, function(a) { +var d = _.get(a, "metadata.name", ""), e = k(a, !0), f = _.indexBy(a.spec.tags, "name"); +_.each(b, function(b) { +b.test(d) || e && b.test(e) || _.each(a.spec.tags, function(a) { +var c = _.get(a, "annotations.tags", ""); +if (!/\bbuilder\b/.test(c)) return void delete f[a.name]; +if (!b.test(a.name)) { +var d = _.get(a, "annotations.description"); +d && b.test(d) || delete f[a.name]; +} +}); +}); +var g; +_.isEmpty(f) || (g = angular.copy(a), g.status.tags = _.filter(g.status.tags, function(a) { +return f[a.tag]; +}), c.push(g)); +}), c; }, m = [ "metadata.name", 'metadata.annotations["openshift.io/display-name"]', "metadata.annotations.description" ], n = function(a, b) { return c.filterForKeywords(a, m, b); }; @@ -10118,12 +10136,16 @@ f[a.name] = c(b.imageStream, a.name), a.from && "ImageStreamTag" === a.from.kind var g = function(a) { var b = _.get(f, [ a ], []); return _.includes(b, "builder"); -}, h = _.get(b, "imageStream.status.tags", []); -b.tags = _.filter(h, function(a) { +}; +b.$watch("imageStream.status.tags", function(a) { +b.tags = _.filter(a, function(a) { return g(a.tag) && !d[a.tag]; }); -var i = _.head(b.tags); -_.set(b, "is.tag", i); +var c = _.get(b, "is.tag.tag"); +c && _.some(b.tags, { +tag:c +}) || _.set(b, "is.tag", _.head(b.tags)); +}); } }; } ]), angular.module("openshiftConsole").directive("catalogTemplate", function() {