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

mendersoftware / gui / 1057188406

01 Nov 2023 04:24AM UTC coverage: 82.824% (-17.1%) from 99.964%
1057188406

Pull #4134

gitlab-ci

web-flow
chore: Bump uuid from 9.0.0 to 9.0.1

Bumps [uuid](https://github.com/uuidjs/uuid) from 9.0.0 to 9.0.1.
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #4134: chore: Bump uuid from 9.0.0 to 9.0.1

4349 of 6284 branches covered (0.0%)

8313 of 10037 relevant lines covered (82.82%)

200.97 hits per line

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

67.39
/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 };
184✔
26

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

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

37
export const FilterItem = ({ attributes, onChange, onSelect, plan, reset }) => {
184✔
38
  const [key, setKey] = useState(emptyFilter.key); // this refers to the selected filter with key as the id
3✔
39
  const [value, setValue] = useState(emptyFilter.value); // while this is the value that is applied with the filter
3✔
40
  const [operator, setOperator] = useState(emptyFilter.operator);
3✔
41
  const [scope, setScope] = useState(emptyFilter.scope);
3✔
42
  const timer = useRef();
3✔
43

44
  useEffect(() => {
3✔
45
    clearTimeout(timer.current);
2✔
46
    setKey(emptyFilter.key);
2✔
47
    setValue(emptyFilter.value);
2✔
48
    setOperator(emptyFilter.operator);
2✔
49
    setScope(emptyFilter.scope);
2✔
50
  }, [attributes.length, reset]);
51

52
  useEffect(() => {
3✔
53
    clearTimeout(timer.current);
2✔
54
    onChange({ key, operator, scope, value });
2✔
55
    timer.current = setTimeout(
2✔
56
      () =>
57
        key && (value || operator.includes('exists'))
×
58
          ? onSelect({
59
              key,
60
              operator,
61
              scope,
62
              value
63
            })
64
          : null,
65
      TIMEOUTS.threeSeconds
66
    );
67
    return () => {
2✔
68
      clearTimeout(timer.current);
2✔
69
    };
70
  }, [key, onChange, onSelect, operator, scope, value]);
71

72
  const updateFilterKey = ({ key, scope }) => {
3✔
73
    setKey(key);
×
74
    setScope(scope);
×
75
  };
76

77
  const updateFilterOperator = ({ target: { value: changedOperator } }) => {
3✔
78
    const operator = DEVICE_FILTERING_OPTIONS[changedOperator] || {};
×
79
    const opValue = operator.value ?? value ?? '';
×
80
    setOperator(changedOperator);
×
81
    setValue(opValue);
×
82
  };
83

84
  const updateFilterValue = ({ target: { value = '' } }) => setValue(value);
3!
85

86
  const removeFilter = useCallback(() => {
3✔
87
    setKey(emptyFilter.key);
×
88
    setValue(emptyFilter.value);
×
89
    setOperator(emptyFilter.operator);
×
90
    setScope(emptyFilter.scope);
×
91
  }, []);
92

93
  const onKeyDown = e => {
3✔
94
    if (e.key !== 'Enter' || ![key, operator, scope, value].every(thing => !!thing)) {
×
95
      return;
×
96
    }
97
    e.preventDefault();
×
98
    onSelect({ key, operator, scope, value });
×
99
  };
100

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

148
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