• 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

81.48
/src/js/components/devices/widgets/attribute-autocomplete.js
1
// Copyright 2022 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 { Autocomplete, TextField, createFilterOptions } from '@mui/material';
18

19
import { TIMEOUTS } from '../../../constants/appConstants';
20
import { emptyFilter } from '../../../constants/deviceConstants';
21
import { defaultHeaders } from '../base-devices';
22
import { getFilterLabelByKey } from './filters';
23

24
const textFieldStyle = { marginTop: 0, marginBottom: 15 };
184✔
25

26
export const getOptionLabel = option => {
184✔
27
  const header = Object.values(defaultHeaders).find(
113✔
28
    ({ attribute }) => attribute.scope === option.scope && (attribute.name === option.key || attribute.alternative === option.key)
552✔
29
  );
30
  return header?.title || option.title || option.value || option.key || option;
113✔
31
};
32

33
const FilterOption = (props, option) => {
184✔
34
  let content = getOptionLabel(option);
20✔
35
  if (option.category === 'recently used') {
20!
36
    content = (
×
37
      <div className="flexbox center-aligned space-between" style={{ width: '100%' }}>
38
        <div>{content}</div>
39
        <div className="muted slightly-smaller">({option.scope})</div>
40
      </div>
41
    );
42
  }
43
  return <li {...props}>{content}</li>;
20✔
44
};
45

46
const optionsFilter = createFilterOptions();
184✔
47

48
const filterOptions = (options, params) => {
184✔
49
  const filtered = optionsFilter(options, params);
9✔
50
  if (filtered.length !== 1 && params.inputValue !== '') {
9✔
51
    filtered.push({
4✔
52
      inputValue: params.inputValue,
53
      key: 'custom',
54
      value: `Use "${params.inputValue}"`,
55
      category: 'custom',
56
      priority: 99
57
    });
58
  }
59
  return filtered;
9✔
60
};
61

62
export const AttributeAutoComplete = ({ attributes, disabled = false, filter = emptyFilter, label = 'Attribute', onRemove, onSelect, ...remainder }) => {
184!
63
  const [key, setKey] = useState(filter.key); // this refers to the selected filter with key as the id
14✔
64
  const [options, setOptions] = useState([]);
14✔
65
  const [reset, setReset] = useState(true);
14✔
66
  const [scope, setScope] = useState(filter.scope);
14✔
67
  const timer = useRef();
14✔
68

69
  useEffect(() => {
14✔
70
    return () => {
4✔
71
      clearTimeout(timer.current);
4✔
72
    };
73
  }, []);
74

75
  useEffect(() => {
14✔
76
    setKey(emptyFilter.key);
6✔
77
    setScope(emptyFilter.scope);
6✔
78
    setOptions(attributes.sort((a, b) => a.priority - b.priority));
12✔
79
    // eslint-disable-next-line react-hooks/exhaustive-deps
80
  }, [attributes.length, reset]);
81

82
  useEffect(() => {
14✔
83
    setKey(filter.key);
4✔
84
  }, [filter.key]);
85

86
  useEffect(() => {
14✔
87
    clearTimeout(timer.current);
8✔
88
    timer.current = setTimeout(() => onSelect({ key, scope }), TIMEOUTS.debounceDefault);
8✔
89
    return () => {
8✔
90
      clearTimeout(timer.current);
8✔
91
    };
92
  }, [key, onSelect, scope]);
93

94
  const updateFilterKey = (value, selectedScope) => {
14✔
95
    if (!value) {
×
96
      return removeFilter();
×
97
    }
98
    const { key = value, scope: fallbackScope } = attributes.find(filter => filter.key === value) ?? {};
×
99
    setKey(key);
×
100
    setScope(selectedScope || fallbackScope);
×
101
  };
102

103
  const removeFilter = useCallback(() => {
14✔
104
    if (key) {
×
105
      onRemove({ key, scope });
×
106
    }
107
    setReset(!reset);
×
108
  }, [key, onRemove, reset, setReset, scope]);
109

110
  return (
14✔
111
    <Autocomplete
112
      {...remainder}
113
      autoComplete
114
      autoHighlight
115
      autoSelect
116
      disabled={disabled}
117
      freeSolo
118
      filterSelectedOptions
119
      filterOptions={filterOptions}
120
      getOptionLabel={getOptionLabel}
121
      groupBy={option => option.category}
20✔
122
      renderOption={FilterOption}
123
      id="filter-selection"
124
      includeInputInList={true}
125
      onChange={(e, changedValue) => {
126
        const { inputValue, key = changedValue, scope } = changedValue || {};
1!
127
        if (inputValue) {
1!
128
          // only circumvent updateFilterKey if we deal with a custom attribute - those will be treated as inventory attributes
129
          setKey(inputValue);
1✔
130
          return setScope(emptyFilter.scope);
1✔
131
        }
132
        updateFilterKey(key, scope);
×
133
      }}
134
      options={options}
135
      renderInput={params => <TextField {...params} label={label} style={textFieldStyle} />}
25✔
136
      key={reset}
137
      value={getFilterLabelByKey(key, attributes)}
138
    />
139
  );
140
};
141

142
export default AttributeAutoComplete;
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