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

eclipsesource / jsonforms / 11500510629

24 Oct 2024 01:38PM UTC coverage: 81.639% (-0.09%) from 81.728%
11500510629

Pull #2346

github

lucas-koehler
fix imports after rebase
Pull Request #2346: Unify path handling to consistenly use JSON Pointer

10134 of 23327 branches covered (43.44%)

38 of 45 new or added lines in 18 files covered. (84.44%)

421 existing lines in 81 files now uncovered.

17305 of 21197 relevant lines covered (81.64%)

27.67 hits per line

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

93.44
/packages/vanilla-renderers/src/complex/TableArrayControl.tsx
1
/*
2
  The MIT License
3
  
4
  Copyright (c) 2017-2019 EclipseSource Munich
5
  https://github.com/eclipsesource/jsonforms
6
  
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
  of this software and associated documentation files (the "Software"), to deal
9
  in the Software without restriction, including without limitation the rights
10
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
  copies of the Software, and to permit persons to whom the Software is
12
  furnished to do so, subject to the following conditions:
13
  
14
  The above copyright notice and this permission notice shall be included in
15
  all copies or substantial portions of the Software.
16
  
17
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
  THE SOFTWARE.
24
*/
25
import React from 'react';
7✔
26
import fpfilter from 'lodash/fp/filter';
7✔
27
import fpmap from 'lodash/fp/map';
7✔
28
import fpflow from 'lodash/fp/flow';
7✔
29
import filter from 'lodash/filter';
7✔
30
import join from 'lodash/join';
7✔
31
import fpkeys from 'lodash/fp/keys';
7✔
32
import fpstartCase from 'lodash/fp/startCase';
7✔
33
import {
7✔
34
  ArrayControlProps,
35
  ControlElement,
36
  createDefaultValue,
37
  Helpers,
38
  Paths,
39
  RankedTester,
40
  Resolve,
41
  Test,
42
  getControlPath,
43
  ArrayTranslations,
44
} from '@jsonforms/core';
45
import {
7✔
46
  DispatchCell,
47
  withArrayTranslationProps,
48
  withJsonFormsArrayControlProps,
49
  withTranslateProps,
50
} from '@jsonforms/react';
51
import { withVanillaControlProps } from '../util';
7✔
52
import type { VanillaRendererProps } from '../index';
53

54
const { convertToValidClassName } = Helpers;
7✔
55

56
const { or, isObjectArrayControl, isPrimitiveArrayControl, rankWith } = Test;
28✔
57

58
/**
59
 * Alternative tester for an array that also checks whether the 'table'
60
 * option is set.
61
 * @type {RankedTester}
62
 */
63
export const tableArrayControlTester: RankedTester = rankWith(
7✔
64
  3,
65
  or(isObjectArrayControl, isPrimitiveArrayControl)
66
);
67

68
class TableArrayControl extends React.Component<
17✔
69
  ArrayControlProps &
70
    VanillaRendererProps & { translations: ArrayTranslations },
71
  any
72
> {
73
  confirmDelete = (path: string, index: number) => {
17✔
NEW
74
    const p = path.substring(0, path.lastIndexOf('/'));
×
75
    this.props.removeItems(p, [index])();
×
76
  };
77

78
  render() {
27✔
79
    const {
80
      addItem,
27✔
81
      uischema,
27✔
82
      schema,
27✔
83
      rootSchema,
27✔
84
      path,
27✔
85
      data,
27✔
86
      visible,
27✔
87
      errors,
27✔
88
      label,
27✔
89
      getStyleAsClassName,
27✔
90
      childErrors,
27✔
91
      translations,
27✔
92
      enabled,
27✔
93
    } = this.props;
27✔
94

95
    const controlElement = uischema as ControlElement;
27✔
96
    const tableClass = getStyleAsClassName('array.table.table');
27✔
97
    const labelClass = getStyleAsClassName('array.table.label');
27✔
98
    const buttonClass = getStyleAsClassName('array.table.button');
27✔
99
    const validationClass = getStyleAsClassName('array.table.validation');
27✔
100
    const controlClass = [
27✔
101
      getStyleAsClassName('array.table'),
102
      convertToValidClassName(controlElement.scope),
103
    ].join(' ');
104
    const createControlElement = (key?: string): ControlElement => ({
44✔
105
      type: 'Control',
106
      label: false,
107
      scope:
108
        schema.type === 'object' ? Paths.compose('#', 'properties', key) : '#',
44✔
109
    });
110
    const isValid = errors.length === 0;
27✔
111
    const divClassNames = [validationClass]
27✔
112
      .concat(
113
        isValid ? '' : getStyleAsClassName('array.table.validation.error')
27✔
114
      )
115
      .join(' ');
116

117
    return (
27✔
118
      <div className={controlClass} hidden={!visible}>
119
        <header>
120
          <label className={labelClass}>{label}</label>
121
          <button
122
            type='button'
123
            disabled={!enabled}
124
            className={buttonClass}
125
            onClick={addItem(path, createDefaultValue(schema, rootSchema))}
126
          >
127
            {translations.addTooltip}
128
          </button>
129
        </header>
130
        <div className={divClassNames}>{!isValid ? errors : ''}</div>
27✔
131
        <table className={tableClass}>
132
          <thead>
133
            <tr>
134
              {schema.properties ? (
27✔
135
                fpflow(
136
                  fpkeys,
137
                  fpfilter((prop) => schema.properties[prop].type !== 'array'),
52✔
138
                  fpmap((prop) => (
52✔
139
                    <th key={prop}>
140
                      {schema.properties[prop].title ?? fpstartCase(prop)}
156✔
141
                    </th>
142
                  ))
143
                )(schema.properties)
144
              ) : (
145
                <th>Items</th>
146
              )}
147
              <th>Valid</th>
148
              <th>&nbsp;</th>
149
            </tr>
150
          </thead>
151
          <tbody>
152
            {!data || !Array.isArray(data) || data.length === 0 ? (
99✔
153
              <tr>
154
                <td>{translations.noDataMessage}</td>
155
              </tr>
156
            ) : (
157
              data.map((_child, index) => {
158
                const childPath = Paths.compose(path, index);
23✔
159
                const errorsPerEntry: any[] = filter(childErrors, (error) => {
23✔
160
                  const errorPath = getControlPath(error);
2✔
161
                  return errorPath.startsWith(childPath);
2✔
162
                });
163

164
                const validationClassName =
165
                  getStyleAsClassName('array.validation');
23✔
166
                const errorValidationClassName = getStyleAsClassName(
23✔
167
                  'array.validation.error'
168
                );
169
                const errorClassNames = errorsPerEntry
23!
170
                  ? [validationClassName]
171
                      .concat(errorValidationClassName)
172
                      .join(' ')
173
                  : validationClassName;
174

175
                return (
23✔
176
                  <tr key={childPath}>
177
                    {schema.properties ? (
23✔
178
                      fpflow(
179
                        fpkeys,
180
                        fpfilter(
181
                          (prop) => schema.properties[prop].type !== 'array'
42✔
182
                        ),
183
                        fpmap((prop) => {
184
                          const childPropPath = Paths.compose(childPath, prop);
42✔
185
                          return (
42✔
186
                            <td key={childPropPath}>
187
                              <DispatchCell
188
                                schema={Resolve.schema(
189
                                  schema,
190
                                  Paths.compose('#', 'properties', prop),
191
                                  rootSchema
192
                                )}
193
                                uischema={createControlElement(prop)}
194
                                path={childPropPath}
195
                              />
196
                            </td>
197
                          );
198
                        })
199
                      )(schema.properties)
200
                    ) : (
201
                      <td key={Paths.compose(childPath, index)}>
202
                        <DispatchCell
203
                          schema={schema}
204
                          uischema={createControlElement()}
205
                          path={childPath}
206
                        />
207
                      </td>
208
                    )}
209
                    <td>
210
                      {errorsPerEntry ? (
23!
211
                        <span className={errorClassNames}>
212
                          {join(
213
                            errorsPerEntry.map((e) => e.message),
1✔
214
                            ' and '
215
                          )}
216
                        </span>
217
                      ) : (
218
                        <span className={errorClassNames}>OK</span>
219
                      )}
220
                    </td>
221
                    <td>
222
                      <button
223
                        type='button'
224
                        disabled={!enabled}
225
                        aria-label={translations.removeAriaLabel}
226
                        onClick={() => {
227
                          if (
×
228
                            window.confirm(translations.deleteDialogMessage)
229
                          ) {
230
                            this.confirmDelete(childPath, index);
×
231
                          }
232
                        }}
233
                      >
234
                        {translations.removeTooltip}
235
                      </button>
236
                    </td>
237
                  </tr>
238
                );
239
              })
240
            )}
241
          </tbody>
242
        </table>
243
      </div>
244
    );
245
  }
246
}
7✔
247

248
export default withVanillaControlProps(
7✔
249
  withJsonFormsArrayControlProps(
250
    withTranslateProps(withArrayTranslationProps(TableArrayControl))
251
  )
252
);
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