summaryrefslogtreecommitdiff
path: root/packages/exchange-backoffice-ui/src/forms/InputArray.tsx
blob: f60ed41602c72992f08391bbe6c9486236a96ab9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import { Fragment, VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { FormProvider } from "./FormProvider.js";
import { LabelWithTooltipMaybeRequired, UIFormProps } from "./InputLine.js";
import { RenderAllFieldsByUiConfig, UIFormField } from "./forms.js";
import { useField } from "./useField.js";

export function InputArray(
  props: {
    fields: UIFormField[];
    labelField: string;
  } & UIFormProps<Array<{}>>,
): VNode {
  const { fields, labelField, name, label, required, tooltip } = props;
  const { value, onChange } = useField<{ [s: string]: Array<any> }>(name);
  const list = value ?? [];
  const [selectedIndex, setSelected] = useState<number | undefined>(undefined);
  const selected =
    selectedIndex === undefined ? undefined : list[selectedIndex];
  const formState = useState(selected ?? {});
  useEffect(() => {
    const [, update] = formState;
    update(selected);
  }, [selected]);
  return (
    <div class="sm:col-span-6">
      <LabelWithTooltipMaybeRequired
        label={label}
        required={required}
        tooltip={tooltip}
      />

      <div class="flex mb-4 items-center pt-3">
        <div class="flex-auto">
          {selectedIndex !== undefined && (
            <button
              type="button"
              onClick={() => {
                setSelected(undefined);
              }}
              class="block rounded-md bg-white px-3 py-2 text-center text-sm font-semibold shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
            >
              Cancel
            </button>
          )}
        </div>
        <div class="flex-none">
          {selectedIndex === undefined && (
            <button
              type="button"
              onClick={() => {
                setSelected(list.length);
              }}
              class="block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm  text-white shadow-sm hover:bg-indigo-500 "
            >
              Add
            </button>
          )}
        </div>
      </div>
      <div class="-space-y-px rounded-md bg-white ">
        {list.map((v, idx) => {
          const isFirst = idx === 0;
          const isLast = idx === list.length - 1;
          const isSelected = selectedIndex === idx;
          const disabled = selectedIndex !== undefined && !isSelected;
          let clazz =
            "relative flex border p-4 focus:outline-none disabled:text-grey";
          if (isFirst) {
            clazz += " rounded-tl-md rounded-tr-md ";
          }
          if (isLast) {
            clazz += " rounded-bl-md rounded-br-md ";
          }
          if (isSelected) {
            clazz += " z-10 border-indigo-200 bg-indigo-50 ";
          } else {
            clazz += " border-gray-200";
          }
          if (disabled) {
            clazz +=
              " cursor-not-allowed bg-gray-50 text-gray-500 ring-gray-200  text-gray";
          } else {
            clazz += " cursor-pointer";
          }
          return (
            <label class={clazz}>
              <Fragment>
                <input
                  type="radio"
                  name="privacy-setting"
                  checked={isSelected}
                  disabled={disabled}
                  onClick={() => setSelected(idx)}
                  class="mt-0.5 h-4 w-4 shrink-0 text-indigo-600 disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 disabled:ring-gray-200  focus:ring-indigo-600"
                  aria-labelledby="privacy-setting-0-label"
                  aria-describedby="privacy-setting-0-description"
                />
                <span class="ml-3 flex flex-col">
                  <span
                    id="privacy-setting-0-label"
                    disabled
                    class="block text-sm font-medium"
                  >
                    {v[labelField]}
                  </span>
                  {/* <!-- Checked: "text-indigo-700", Not Checked: "text-gray-500" --> */}
                  {/* <span
                    id="privacy-setting-0-description"
                    class="block text-sm"
                  >
                    This project would be available to anyone who has the link
                  </span> */}
                </span>
              </Fragment>
            </label>
          );
        })}
      </div>
      {selectedIndex !== undefined && (
        <FormProvider state={formState}>
          <div class="px-4 py-6">
            <div class="grid grid-cols-1 gap-y-8 ">
              <RenderAllFieldsByUiConfig fields={fields} />
            </div>
          </div>
        </FormProvider>
      )}
      {selectedIndex !== undefined && (
        <div class="flex items-center pt-3">
          <div class="flex-auto">
            {selected !== undefined && (
              <button
                type="button"
                onClick={() => {
                  const newValue = [...list];
                  newValue.splice(selectedIndex, 1);
                  onChange(newValue);
                  setSelected(undefined);
                }}
                class="block rounded-md bg-red-600 px-3 py-2 text-center text-sm  text-white shadow-sm hover:bg-red-500 "
              >
                Remove
              </button>
            )}
          </div>
          <div class="flex-none">
            <button
              type="button"
              onClick={() => {
                const newValue = [...list];
                const [confirmed] = formState;
                newValue.splice(selectedIndex, 1, confirmed);
                onChange(newValue);
                setSelected(undefined);
              }}
              class="block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm  text-white shadow-sm hover:bg-indigo-500 "
            >
              Confirm
            </button>
          </div>
        </div>
      )}
    </div>
  );
}