fix: строка добавленных служб на АРМ ДДС без пустого значения, пикер с лимитом 20 и без служб из notify
This commit is contained in:
parent
f9d2c2cc77
commit
01e128c22d
2 changed files with 28 additions and 9 deletions
|
|
@ -19,6 +19,7 @@ interface Props {
|
||||||
export function KioCard({ state, required = [], readOnly = false, referenceArm = false, onChange }: Props) {
|
export function KioCard({ state, required = [], readOnly = false, referenceArm = false, onChange }: Props) {
|
||||||
const dds = display(state, "dds") as string | null;
|
const dds = display(state, "dds") as string | null;
|
||||||
const incidentGroup = display(state, "incident_group") as number | null;
|
const incidentGroup = display(state, "incident_group") as number | null;
|
||||||
|
const notify = (display(state, "notify") as string[] | null) ?? [];
|
||||||
const groups = visibleGroups(dds);
|
const groups = visibleGroups(dds);
|
||||||
const section = (group: FieldGroup) => (
|
const section = (group: FieldGroup) => (
|
||||||
<section className={`kio-arm-section kio-arm-${group.area}`} key={group.title}>
|
<section className={`kio-arm-section kio-arm-${group.area}`} key={group.title}>
|
||||||
|
|
@ -38,6 +39,7 @@ export function KioCard({ state, required = [], readOnly = false, referenceArm =
|
||||||
readOnly={readOnly || field.readOnly}
|
readOnly={readOnly || field.readOnly}
|
||||||
referenceArm={referenceArm}
|
referenceArm={referenceArm}
|
||||||
incidentGroup={incidentGroup}
|
incidentGroup={incidentGroup}
|
||||||
|
notify={notify}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
@ -60,7 +62,7 @@ export function KioCard({ state, required = [], readOnly = false, referenceArm =
|
||||||
}
|
}
|
||||||
|
|
||||||
function Row({
|
function Row({
|
||||||
field, value, pending, required, readOnly, referenceArm, incidentGroup, onChange,
|
field, value, pending, required, readOnly, referenceArm, incidentGroup, notify, onChange,
|
||||||
}: {
|
}: {
|
||||||
field: Field;
|
field: Field;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
|
|
@ -69,6 +71,7 @@ function Row({
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
referenceArm: boolean;
|
referenceArm: boolean;
|
||||||
incidentGroup: number | null;
|
incidentGroup: number | null;
|
||||||
|
notify: string[];
|
||||||
onChange?: (path: string, value: unknown) => void;
|
onChange?: (path: string, value: unknown) => void;
|
||||||
}) {
|
}) {
|
||||||
const empty = value === null || value === undefined || value === "" || (Array.isArray(value) && value.length === 0);
|
const empty = value === null || value === undefined || value === "" || (Array.isArray(value) && value.length === 0);
|
||||||
|
|
@ -87,7 +90,7 @@ function Row({
|
||||||
{readOnly ? (
|
{readOnly ? (
|
||||||
<span className="kio-arm-readonly">{formatValue(value, field)}</span>
|
<span className="kio-arm-readonly">{formatValue(value, field)}</span>
|
||||||
) : (
|
) : (
|
||||||
<Input field={field} value={value} referenceArm={referenceArm} incidentGroup={incidentGroup} onChange={onChange} />
|
<Input field={field} value={value} referenceArm={referenceArm} incidentGroup={incidentGroup} notify={notify} onChange={onChange} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -95,12 +98,13 @@ function Row({
|
||||||
}
|
}
|
||||||
|
|
||||||
function Input({
|
function Input({
|
||||||
field, value, referenceArm, incidentGroup, onChange,
|
field, value, referenceArm, incidentGroup, notify, onChange,
|
||||||
}: {
|
}: {
|
||||||
field: Field;
|
field: Field;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
referenceArm: boolean;
|
referenceArm: boolean;
|
||||||
incidentGroup: number | null;
|
incidentGroup: number | null;
|
||||||
|
notify: string[];
|
||||||
onChange?: (path: string, value: unknown) => void;
|
onChange?: (path: string, value: unknown) => void;
|
||||||
}) {
|
}) {
|
||||||
const emit = (next: unknown) => onChange?.(field.path, next);
|
const emit = (next: unknown) => onChange?.(field.path, next);
|
||||||
|
|
@ -144,7 +148,7 @@ function Input({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (field.kind === "services") {
|
if (field.kind === "services") {
|
||||||
return <ServicesPicker value={(value as string[]) ?? []} onChange={(next) => emit(next)} />;
|
return <ServicesPicker value={(value as string[]) ?? []} notify={notify} onChange={(next) => emit(next)} />;
|
||||||
}
|
}
|
||||||
if (field.kind === "signs") {
|
if (field.kind === "signs") {
|
||||||
return <SignsPicker value={(value as string[]) ?? []} group={incidentGroup} onChange={(next) => emit(next)} />;
|
return <SignsPicker value={(value as string[]) ?? []} group={incidentGroup} onChange={(next) => emit(next)} />;
|
||||||
|
|
@ -175,15 +179,24 @@ function Input({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Как `max_length` у `KIO.notify_extra`. */
|
||||||
|
const SERVICES_LIMIT = 20;
|
||||||
|
|
||||||
/** Ручное добавление служб из каталога — окно «Добавьте службы» боевого АРМ.
|
/** Ручное добавление служб из каталога — окно «Добавьте службы» боевого АРМ.
|
||||||
* Список оповещения по признакам остаётся как есть: здесь только добавки. */
|
* Список оповещения по признакам остаётся как есть: здесь только добавки. */
|
||||||
function ServicesPicker({ value, onChange }: { value: string[]; onChange: (next: string[]) => void }) {
|
function ServicesPicker({ value, notify, onChange }: {
|
||||||
|
value: string[]; notify: string[]; onChange: (next: string[]) => void;
|
||||||
|
}) {
|
||||||
const catalog = useServiceCatalog();
|
const catalog = useServiceCatalog();
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
const needle = query.trim().toLowerCase();
|
const needle = query.trim().toLowerCase();
|
||||||
const found = needle
|
// Лимит и службы из списка оповещения — те же правила, что на сервере:
|
||||||
|
// лишняя служба отклонила бы весь пакет правок.
|
||||||
|
const full = value.length >= SERVICES_LIMIT;
|
||||||
|
const found = needle && !full
|
||||||
? (catalog.data?.services ?? [])
|
? (catalog.data?.services ?? [])
|
||||||
.filter((item) => !value.includes(item.name) && item.name.toLowerCase().includes(needle))
|
.filter((item) => !value.includes(item.name) && !notify.includes(item.name)
|
||||||
|
&& item.name.toLowerCase().includes(needle))
|
||||||
.slice(0, 8)
|
.slice(0, 8)
|
||||||
: [];
|
: [];
|
||||||
return (
|
return (
|
||||||
|
|
@ -194,7 +207,8 @@ function ServicesPicker({ value, onChange }: { value: string[]; onChange: (next:
|
||||||
onClick={() => onChange(value.filter((item) => item !== name))}>×</button>
|
onClick={() => onChange(value.filter((item) => item !== name))}>×</button>
|
||||||
</span>)}
|
</span>)}
|
||||||
</div>}
|
</div>}
|
||||||
<input type="search" aria-label="Поиск службы в каталоге" placeholder="Поиск службы…"
|
<input type="search" aria-label="Поиск службы в каталоге"
|
||||||
|
placeholder={full ? `Не больше ${SERVICES_LIMIT} служб` : "Поиск службы…"} disabled={full}
|
||||||
value={query} onChange={(event) => setQuery(event.target.value)} />
|
value={query} onChange={(event) => setQuery(event.target.value)} />
|
||||||
{found.length > 0 && <ul className="kio-services-found">
|
{found.length > 0 && <ul className="kio-services-found">
|
||||||
{found.map((item) => <li key={item.id}>
|
{found.map((item) => <li key={item.id}>
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,11 @@ function field(card: CardState, path: string): string {
|
||||||
const value = readPath(card.server, path);
|
const value = readPath(card.server, path);
|
||||||
return value === null || value === undefined || value === "" ? "—" : String(value);
|
return value === null || value === undefined || value === "" ? "—" : String(value);
|
||||||
}
|
}
|
||||||
|
/** Список из карточки: `field()` не годится — `String([])` пустая строка, а не «—». */
|
||||||
|
function names(card: CardState, path: string): string[] {
|
||||||
|
const value = readPath(card.server, path);
|
||||||
|
return Array.isArray(value) ? value.map(String) : [];
|
||||||
|
}
|
||||||
function time(value: string): string {
|
function time(value: string): string {
|
||||||
const parsed = new Date(value);
|
const parsed = new Date(value);
|
||||||
return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleTimeString("ru-RU");
|
return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleTimeString("ru-RU");
|
||||||
|
|
@ -548,7 +553,7 @@ export function Dds() {
|
||||||
<div><b>{field(card, "description")}</b></div>
|
<div><b>{field(card, "description")}</b></div>
|
||||||
<div>Класс: <b>{field(card, "incident_type")}</b></div>
|
<div>Класс: <b>{field(card, "incident_type")}</b></div>
|
||||||
<div>Получатели карточки: <b>{station?.recipient_services?.join(", ") || field(card, "notify")}</b></div>
|
<div>Получатели карточки: <b>{station?.recipient_services?.join(", ") || field(card, "notify")}</b></div>
|
||||||
{field(card, "notify_extra") !== "—" && <div>Добавлены оператором: <b>{field(card, "notify_extra")}</b></div>}
|
{names(card, "notify_extra").length > 0 && <div>Добавлены оператором: <b>{names(card, "notify_extra").join(", ")}</b></div>}
|
||||||
<div>Ваша ДДС: <b>{station?.managed_service || "служба не назначена"}</b></div></div>
|
<div>Ваша ДДС: <b>{station?.managed_service || "служба не назначена"}</b></div></div>
|
||||||
</div>
|
</div>
|
||||||
<div className="dds-case-stage">
|
<div className="dds-case-stage">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue