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

mendersoftware / gui / 963124858

pending completion
963124858

Pull #3870

gitlab-ci

mzedel
chore: cleaned up left over onboarding tooltips & aligned with updated design

Signed-off-by: Manuel Zedel <manuel.zedel@northern.tech>
Pull Request #3870: MEN-5413

4368 of 6355 branches covered (68.73%)

91 of 118 new or added lines in 22 files covered. (77.12%)

1753 existing lines in 162 files now uncovered.

8246 of 10042 relevant lines covered (82.12%)

193.52 hits per line

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

72.15
/src/js/components/devices/widgets/filteritem.js
1
// Copyright 2019 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import React, { useCallback, useEffect, useRef, useState } from 'react';
15

16
// material ui
17
import { HighlightOff as HighlightOffIcon } from '@mui/icons-material';
18
import { FormHelperText, IconButton, MenuItem, Select, TextField } from '@mui/material';
19

20
import { TIMEOUTS } from '../../../constants/appConstants';
21
import { DEVICE_FILTERING_OPTIONS, emptyFilter } from '../../../constants/deviceConstants';
22
import { HELPTOOLTIPS, MenderHelpTooltip } from '../../helptips/helptooltips';
23
import AttributeAutoComplete from './attribute-autocomplete';
24

25
const textFieldStyle = { marginTop: 0, marginBottom: 15 };
13✔
26

27
const filterOptionsByPlan = {
13✔
28
  os: { $eq: { title: 'equals' } },
29
  professional: DEVICE_FILTERING_OPTIONS,
30
  enterprise: DEVICE_FILTERING_OPTIONS
31
};
32

33
const defaultScope = 'inventory';
13✔
34

35
const filterNotifications = {
13✔
36
  name: <MenderHelpTooltip id={HELPTOOLTIPS.nameFilterTip.id} style={{ position: 'absolute', top: 20, left: -28 }} />
37
};
38

39
export const FilterItem = ({ attributes, filter, onRemove, onSelect, plan }) => {
13✔
40
  const [key, setKey] = useState(filter.key || ''); // this refers to the selected filter with key as the id
4✔
41
  const [value, setValue] = useState(filter.value || ''); // while this is the value that is applied with the filter
4✔
42
  const [operator, setOperator] = useState(filter.operator || '$eq');
4✔
43
  const [scope, setScope] = useState(filter.scope || defaultScope);
4✔
44
  const [reset, setReset] = useState(true);
4✔
45
  const timer = useRef();
4✔
46

47
  useEffect(() => {
4✔
48
    return () => {
2✔
49
      clearTimeout(timer.current);
2✔
50
    };
51
  }, []);
52

53
  useEffect(() => {
4✔
54
    setKey(emptyFilter.key);
2✔
55
    setValue(emptyFilter.value);
2✔
56
    setOperator(emptyFilter.operator);
2✔
57
    setScope(emptyFilter.scope);
2✔
58
  }, [attributes.length, reset]);
59

60
  useEffect(() => {
4✔
61
    setKey(filter.key);
2✔
62
    setValue(filter.value);
2✔
63
    setOperator(filter.operator);
2✔
64
    setScope(filter.scope);
2✔
65
  }, [filter.key, filter.operator, filter.scope, filter.value]);
66

67
  useEffect(() => {
4✔
68
    clearTimeout(timer.current);
4✔
69
    timer.current = setTimeout(
4✔
70
      () =>
UNCOV
71
        key && (value || operator.includes('exists'))
×
72
          ? onSelect({
73
              key,
74
              operator,
75
              scope,
76
              value
77
            })
78
          : null,
79
      TIMEOUTS.debounceDefault
80
    );
81
  }, [key, onSelect, operator, scope, value]);
82

83
  const updateFilterKey = ({ key, scope }) => {
4✔
UNCOV
84
    setKey(key);
×
UNCOV
85
    setScope(scope);
×
86
  };
87

88
  const updateFilterOperator = ({ target: { value: changedOperator } }) => {
4✔
UNCOV
89
    const operator = DEVICE_FILTERING_OPTIONS[changedOperator] || {};
×
UNCOV
90
    const opValue = operator.value ?? value ?? '';
×
UNCOV
91
    setOperator(changedOperator);
×
UNCOV
92
    setValue(opValue);
×
93
  };
94

95
  const updateFilterValue = ({ target: { value = '' } }) => {
4!
UNCOV
96
    setValue(value);
×
97
  };
98

99
  const removeFilter = useCallback(() => {
4✔
UNCOV
100
    onRemove({ key, operator, scope, value });
×
UNCOV
101
    setReset(!reset);
×
102
  }, [key, onRemove, operator, reset, scope, setReset, value]);
103

104
  const filterOptions = plan ? filterOptionsByPlan[plan] : DEVICE_FILTERING_OPTIONS;
4✔
105
  const operatorHelpMessage = (DEVICE_FILTERING_OPTIONS[operator] || {}).help || '';
4✔
106
  const showValue = typeof (filterOptions[operator] || {}).value === 'undefined';
4✔
107
  return (
4✔
108
    <>
109
      <div className="flexbox center-aligned relative">
110
        {filterNotifications[key]}
111
        <AttributeAutoComplete attributes={attributes} filter={filter} label="Attribute" onRemove={removeFilter} onSelect={updateFilterKey} />
112
        <Select className="margin-left-small margin-right-small" onChange={updateFilterOperator} value={operator}>
113
          {Object.entries(filterOptions).map(([optionKey, option]) => (
114
            <MenuItem key={optionKey} value={optionKey}>
24✔
115
              {option.title}
116
            </MenuItem>
117
          ))}
118
        </Select>
119
        {showValue && <TextField label="Value" value={value} onChange={updateFilterValue} InputLabelProps={{ shrink: !!value }} style={textFieldStyle} />}
8✔
120
        {!!key && (
6✔
121
          <IconButton className="margin-left" onClick={removeFilter} size="small">
122
            <HighlightOffIcon />
123
          </IconButton>
124
        )}
125
      </div>
126
      {operatorHelpMessage && (
4!
127
        <div className="margin-bottom-small">
128
          <FormHelperText>{operatorHelpMessage}</FormHelperText>
129
        </div>
130
      )}
131
    </>
132
  );
133
};
134

135
export default FilterItem;
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

© 2025 Coveralls, Inc