• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RoundingWell / care-ops-frontend / 8578fbce-015a-4730-917b-48b05950f08b

12 Aug 2025 03:11PM UTC coverage: 95.097% (-4.9%) from 100.0%
8578fbce-015a-4730-917b-48b05950f08b

push

circleci

web-flow
Merge pull request #1489 from RoundingWell/pt-search-tweak

In search results, don't show match column data if `match.label` equals `Name` or `Birth Date`

1757 of 1845 branches covered (95.23%)

Branch coverage included in aggregate %.

3 of 3 new or added lines in 1 file covered. (100.0%)

307 existing lines in 33 files now uncovered.

5905 of 6212 relevant lines covered (95.06%)

195.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.42
/src/js/views/programs/program/workflows/workflows_views.js
1
import Radio from 'backbone.radio';
2

3
import hbs from 'handlebars-inline-precompile';
4
import { View, CollectionView, Behavior } from 'marionette';
5

6
import { alphaSort } from 'js/utils/sorting';
7

8
import 'scss/modules/buttons.scss';
9
import 'scss/modules/table-list.scss';
10

11
import { PROGRAM_BEHAVIORS } from 'js/static';
12
import intl from 'js/i18n';
13

14
import Droplist from 'js/components/droplist';
15

16
import PreloadRegion from 'js/regions/preload_region';
17

18
import { OwnerComponent as FlowOwnerComponent } from 'js/views/programs/shared/flows_views';
19
import { DueDayComponent, OwnerComponent, BehaviorComponent } from 'js/views/programs/shared/actions_views';
20

21
import ActionItemTemplate from './action-item.hbs';
22
import FlowItemTemplate from './flow-item.hbs';
23
import LayoutTemplate from './layout.hbs';
24

25
import 'scss/domain/program-action-state.scss';
26
import './workflows.scss';
27

28
const EmptyView = View.extend({
146✔
29
  tagName: 'tr',
30
  template: hbs`
31
    <td class="workflows__empty-list">
32
      <h2>{{ @intl.programs.program.workflows.workflowsViews.emptyView }}</h2>
33
    </td>
34
  `,
35
});
36

37
const RowBehavior = Behavior.extend({
146✔
38
  modelEvents: {
39
    'editing': 'onEditing',
40
    'change': 'onChange',
41
  },
42
  onChange() {
43
    this.view.render();
2✔
44
  },
45
  onEditing(isEditing) {
46
    this.$el.toggleClass('is-selected', isEditing);
7✔
47
  },
48
  onInitialize() {
49
    if (this.view.model.isNew()) this.$el.addClass('is-selected');
51✔
50
  },
51
});
52

53
const ActionItemView = View.extend({
146✔
54
  className: 'table-list__item',
55
  tagName: 'tr',
56
  behaviors: [RowBehavior],
57
  regions: {
58
    behavior: '[data-behavior-region]',
59
    owner: '[data-owner-region]',
60
    due: '[data-due-region]',
61
  },
62
  template: ActionItemTemplate,
63
  templateContext() {
64
    return {
31✔
65
      hasForm: this.model.getForm(),
66
      icon: this.model.hasOutreach() ? 'share-from-square' : 'file-lines',
31!
67
    };
68
  },
69
  triggers: {
70
    'click': 'click',
71
  },
72
  onClick() {
73
    if (this.model.isNew()) {
1!
UNCOV
74
      Radio.trigger('event-router', 'program:action:new', this.model.getProgram().id);
×
UNCOV
75
      return;
×
76
    }
77

78
    Radio.trigger('event-router', 'program:action', this.model.getProgram().id, this.model.id);
1✔
79
  },
80
  onRender() {
81
    this.showBehavior();
31✔
82
    this.showOwner();
31✔
83
    this.showDue();
31✔
84
  },
85
  showBehavior() {
86
    const isDisabled = this.model.isNew();
31✔
87
    const isFromFlow = !!this.model.getProgramFlow();
31✔
88
    const behaviorComponent = new BehaviorComponent({
31✔
89
      isConditionalAvailable: isFromFlow,
90
      behavior: this.model.get('behavior'),
91
      isCompact: true,
92
      state: { isDisabled },
93
    });
94

95
    this.listenTo(behaviorComponent, 'change:status', ({ behavior }) => {
31✔
UNCOV
96
      this.model.save({ behavior });
×
97
    });
98

99
    this.showChildView('behavior', behaviorComponent);
31✔
100
  },
101
  showOwner() {
102
    const isDisabled = this.model.isNew();
31✔
103
    const isFromFlow = !!this.model.getProgramFlow();
31✔
104
    const ownerComponent = new OwnerComponent({ owner: this.model.getOwner(), isFromFlow, isCompact: true, state: { isDisabled } });
31✔
105

106
    this.listenTo(ownerComponent, 'change:owner', owner => {
31✔
UNCOV
107
      this.model.saveOwner(owner);
×
108
    });
109

110
    this.showChildView('owner', ownerComponent);
31✔
111
  },
112
  showDue() {
113
    const isDisabled = this.model.isNew();
31✔
114
    const dueDayComponent = new DueDayComponent({ day: this.model.get('days_until_due'), isCompact: true, state: { isDisabled } });
31✔
115

116
    this.listenTo(dueDayComponent, 'change:day', day => {
31✔
UNCOV
117
      this.model.save({ days_until_due: day });
×
118
    });
119

120
    this.showChildView('due', dueDayComponent);
31✔
121
  },
122
});
123

124
const FlowItemView = View.extend({
146✔
125
  className: 'table-list__item',
126
  tagName: 'tr',
127
  behaviors: [RowBehavior],
128
  regions: {
129
    owner: '[data-owner-region]',
130
  },
131
  template: FlowItemTemplate,
132
  templateContext() {
133
    return {
22✔
134
      published: !!this.model.get('published_at'),
135
      isAutomated: this.model.get('behavior') === PROGRAM_BEHAVIORS.AUTOMATED,
136
    };
137
  },
138
  triggers: {
139
    'click': 'click',
140
  },
141
  onClick() {
UNCOV
142
    if (this.model.isNew()) {
×
UNCOV
143
      Radio.trigger('event-router', 'programFlow:new', this.model.getProgram().id);
×
UNCOV
144
      return;
×
145
    }
146

UNCOV
147
    Radio.trigger('event-router', 'programFlow', this.model.id);
×
148
  },
149
  onRender() {
150
    this.showOwner();
22✔
151
  },
152
  showOwner() {
153
    const isDisabled = this.model.isNew();
22✔
154
    const ownerComponent = new FlowOwnerComponent({ owner: this.model.getOwner(), isCompact: true, state: { isDisabled } });
22✔
155

156
    this.listenTo(ownerComponent, 'change:owner', owner => {
22✔
UNCOV
157
      this.model.saveOwner(owner);
×
158
    });
159

160
    this.showChildView('owner', ownerComponent);
22✔
161
  },
162
});
163

164
const ListView = CollectionView.extend({
146✔
165
  className: 'table-list workflows__list',
166
  tagName: 'table',
167
  childView(item) {
168
    if (item.type === 'program-flows') {
51✔
169
      return FlowItemView;
21✔
170
    }
171

172
    return ActionItemView;
30✔
173
  },
174
  emptyView: EmptyView,
175
  viewComparator(viewA, viewB) {
176
    return alphaSort('desc', viewA.model.get('updated_at'), viewB.model.get('updated_at'));
90✔
177
  },
178
});
179

180
const LayoutView = View.extend({
146✔
181
  className: 'flex-region workflows__content',
182
  regions: {
183
    content: {
184
      el: '[data-content-region]',
185
      regionClass: PreloadRegion,
186
      replaceElement: true,
187
    },
188
    add: '[data-add-region]',
189
  },
190
  template: LayoutTemplate,
191
});
192

193
const AddActionDroplist = Droplist.extend({
146✔
194
  popWidth: 248,
195
  picklistOptions() {
196
    return {
3✔
197
      headingText: intl.programs.program.workflows.workflowsViews.addActionHeading,
198
      itemClassName: 'u-text--italic',
199
    };
200
  },
201
  viewOptions: {
202
    className: 'button-primary',
203
    template: hbs`{{far "circle-plus"}}<span>{{ @intl.programs.program.workflows.workflowsViews.addAction }}</span>{{far "angle-down" classes="workflows__arrow"}}`,
204
  },
205
  picklistEvents: {
206
    'picklist:item:select': 'onSelect',
207
  },
208
  onSelect({ model }) {
209
    model.get('onSelect')();
3✔
210
  },
211
});
212

213
export {
214
  ListView,
215
  LayoutView,
216
  AddActionDroplist,
217
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc