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

stacklok / codegate-ui / 13202272388

07 Feb 2025 02:53PM UTC coverage: 66.205% (-2.8%) from 69.045%
13202272388

Pull #276

github

web-flow
Merge 0f0595dbf into dbbc8531f
Pull Request #276: Improve user experience workspcaes

391 of 681 branches covered (57.42%)

Branch coverage included in aggregate %.

42 of 84 new or added lines in 13 files covered. (50.0%)

1 existing line in 1 file now uncovered.

853 of 1198 relevant lines covered (71.2%)

71.92 hits per line

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

0.0
/src/forms/rerenders/SelectionArrayRenderer.tsx
1
import type {
2
  ArrayControlProps,
3
  DispatchPropsOfControl,
4
} from "@jsonforms/core";
5
import type { JsonFormsStateContext } from "@jsonforms/react";
6
import {
7
  withJsonFormsArrayControlProps,
8
  withJsonFormsContext,
9
} from "@jsonforms/react";
10
import { Add } from "@mui/icons-material";
11
import {
12
  Button,
13
  FormControl,
14
  IconButton,
15
  InputLabel,
16
  TextField,
17
} from "@mui/material";
18
import React, { useCallback } from "react";
19

20
import type { ProfileEntityType } from "@/types/common";
21
import { RemoveIcon } from "@/ui-kit/icons";
22

23
import { MenuItem } from "../components/MenuItem";
24
import { Select } from "../components/Select";
25

26
interface SelectionItem {
27
  entity: ProfileEntityType | undefined;
28
  selector: string | undefined;
29
}
30

31
interface Props {
32
  props: Omit<ArrayControlProps, "data"> & {
33
    handleChange?: DispatchPropsOfControl["handleChange"];
34
    data: SelectionItem[];
35
  };
36
  ctx: JsonFormsStateContext;
37
}
38

NEW
39
const SelectionArrayRenderer = ({ props, ctx }: Props) => {
×
NEW
40
  const { data = [], path, handleChange, removeItems, addItem, schema } = props;
×
NEW
41
  const validationMode = ctx.core ? ctx.core.validationMode : "ValidateAndHide";
×
NEW
42
  const requiredFields = schema.required ?? [];
×
NEW
43
  const isSelectorRequired = requiredFields.includes("selector");
×
NEW
44
  const isEntityRequired = requiredFields.includes("entity");
×
45

NEW
46
  const handleAddItem = useCallback(() => {
×
NEW
47
    const newItem = {};
×
NEW
48
    addItem(path, newItem)();
×
49
  }, [addItem, path]);
50

NEW
51
  const handleRemoveItem = useCallback(
×
52
    (index: number) => {
NEW
53
      if (removeItems) {
×
NEW
54
        removeItems(path, [index])();
×
55
      }
56
    },
57
    [removeItems, path],
58
  );
59

NEW
60
  const handleItemChange = useCallback(
×
61
    (index: number, field: "entity" | "selector", value: string) => {
NEW
62
      const values = data.map((item, i) =>
×
NEW
63
        i === index ? { ...item, [field]: value } : item,
×
64
      );
NEW
65
      if (data === values) return;
×
NEW
66
      if (handleChange) {
×
NEW
67
        handleChange(path, values);
×
68
      }
69
    },
70
    [path, data, handleChange],
71
  );
72

73
  return (
74
    <div className="flex flex-col space-y-4">
75
      {data.map((item, index) => {
NEW
76
        const isNotFirstChild = index > 0;
×
NEW
77
        const hasNotEntity = item.entity === undefined;
×
78
        const showEntityErrors =
NEW
79
          hasNotEntity && validationMode === "ValidateAndShow";
×
80
        const showSelectorsErrors =
NEW
81
          item.selector === undefined && validationMode === "ValidateAndShow";
×
82

83
        return (
84
          <div className="flex w-full items-center gap-4" key={index}>
85
            <FormControl className="w-60">
86
              {hasNotEntity && (
×
87
                <InputLabel id="demo-simple-select-label">Select</InputLabel>
88
              )}
89
              <Select
90
                {...(hasNotEntity && { label: "Select" })}
×
91
                value={item.entity ?? ""}
×
92
                required={isEntityRequired}
93
                error={
94
                  showEntityErrors ? requiredFields.includes("entity") : false
×
95
                }
96
                onChange={(event) =>
NEW
97
                  handleItemChange(
×
98
                    index,
99
                    "entity",
100
                    event.target.value as string,
101
                  )
102
                }
103
              >
104
                {(schema.properties?.entity.oneOf ?? []).map((option) => (
×
105
                  <MenuItem key={option.const} value={option.const}>
106
                    {option.title}
107
                  </MenuItem>
108
                ))}
109
              </Select>
110
            </FormControl>
111
            <TextField
112
              fullWidth
113
              error={
114
                showSelectorsErrors
×
115
                  ? requiredFields.includes("selector")
116
                  : false
117
              }
118
              required={isSelectorRequired}
119
              value={item.selector ?? ""}
×
120
              onChange={(event) =>
NEW
121
                handleItemChange(index, "selector", event.target.value)
×
122
              }
123
            />
124
            {isNotFirstChild && (
×
125
              <IconButton
126
                color="secondary"
127
                size="small"
NEW
128
                onClick={() => handleRemoveItem(index)}
×
129
              >
130
                <RemoveIcon />
131
              </IconButton>
132
            )}
133
          </div>
134
        );
135
      })}
136
      <div className="mt-4">
137
        <Button variant="outlined" color="primary" onClick={handleAddItem}>
138
          <Add /> Add another selector
139
        </Button>
140
      </div>
141
    </div>
142
  );
143
};
144

145
export default withJsonFormsArrayControlProps(
146
  withJsonFormsContext(SelectionArrayRenderer),
147
  true,
148
);
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