2222 </v-list-item >
2323 </v-list >
2424 </v-menu >
25- <div class =" publish-status" >
26- <publishing-badge :activity =" activity" />
27- <span class =" pl-1" >
28- {{ isPublishing ? publishStatus.message : publishedAtMessage }}
29- </span >
25+ <div :class =" { 'mt-4': !hideDetails }" class =" d-flex align-center" >
26+ <v-tooltip open-delay =" 100" max-width =" 300" left >
27+ <template v-slot :activator =" { on } " >
28+ <span v-on =" on" >
29+ <v-badge :color =" badgeColor" inline dot />
30+ <span v-if =" !hideDetails" class =" ml-1" >
31+ {{ isPublishing ? publishStatus.message : publishDetails }}
32+ </span >
33+ </span >
34+ </template >
35+ <span class =" pl-1" >
36+ {{ publishedAtMessage }}
37+ </span >
38+ </v-tooltip >
3039 </div >
3140 </span >
3241</template >
3342
3443<script >
44+ import { getDescendants , getLabel , isChanged } from ' @/utils/activity' ;
45+ import countBy from ' lodash/countBy' ;
3546import fecha from ' fecha' ;
36- import { getDescendants } from ' utils/activity ' ;
47+ import filter from ' lodash/filter ' ;
3748import { getLevel } from ' shared/activities' ;
49+ import map from ' lodash/map' ;
3850import { mapActions } from ' vuex' ;
39- import PublishingBadge from ' ./Badge ' ;
51+ import pluralize from ' pluralize ' ;
4052import publishMixin from ' components/common/mixins/publish' ;
4153
54+ const getDescriptor = (count , type ) => ` ${ count} ${ pluralize (type, count)} ` ;
55+ const arrayToSentence = arr => arr .join (' , ' ).replace (/ , ([^ ,] * )$ / , ' and $1' );
56+ const getActivityInfo = hasChanges => hasChanges ? ' Has unpublished changes' : ' Published' ;
57+ const getDescendantsInfo = (descendants , count , label ) => {
58+ return ` ${ descendants} within this ${ label} ${ pluralize (' has' , count)}
59+ unpublished changes.` ;
60+ };
61+
4262export default {
4363 mixins: [publishMixin],
4464 props: {
4565 activity: { type: Object , required: true },
4666 outlineActivities: { type: Array , required: true },
67+ hideDetails: { type: Boolean , default: false },
4768 hidePublish: { type: Boolean , default: false }
4869 },
4970 computed: {
@@ -54,19 +75,46 @@ export default {
5475 ? ` Published on ${ fecha .format (new Date (publishedAt), ' M/D/YY h:mm A' )} `
5576 : ' Not published' ;
5677 },
78+ publishDetails () {
79+ const {
80+ activity: { publishedAt },
81+ activityInfo ,
82+ descendantsInfo ,
83+ subtreeHasChanges
84+ } = this ;
85+
86+ if (! publishedAt) return ' Not published' ;
87+ if (subtreeHasChanges) return descendantsInfo;
88+ return activityInfo;
89+ },
5790 activityWithDescendants ({ outlineActivities, activity } = this ) {
5891 return [... getDescendants (outlineActivities, activity), activity];
92+ },
93+ label () {
94+ return getLabel (this .activity );
95+ },
96+ hasChanges () {
97+ return isChanged (this .activity );
98+ },
99+ changedDescendants () {
100+ return filter (getDescendants (this .outlineActivities , this .activity ), isChanged);
101+ },
102+ subtreeHasChanges () {
103+ return !! this .changedDescendants .length ;
104+ },
105+ activityInfo () {
106+ return getActivityInfo (this .hasChanges );
107+ },
108+ descendantsInfo () {
109+ const { changedDescendants , label } = this ;
110+ const labelCountMap = countBy (changedDescendants, getLabel);
111+ const descendants = arrayToSentence (map (labelCountMap, getDescriptor));
112+ return getDescendantsInfo (descendants, changedDescendants .length , label);
113+ },
114+ badgeColor () {
115+ return this .hasChanges || this .subtreeHasChanges ? ' orange' : ' green' ;
59116 }
60117 },
61- methods: mapActions (' repository/activities' , { publishActivity: ' publish' }),
62- components: { PublishingBadge }
118+ methods: mapActions (' repository/activities' , { publishActivity: ' publish' })
63119};
64120 </script >
65-
66- <style lang="scss" scoped>
67- .publish-status {
68- display : flex ;
69- align-items : center ;
70- padding : 1.125rem 0.375rem 0 0.25rem ;
71- }
72- </style >
0 commit comments