/* eslint-disable complexity */
import * as React from "react";
import { AccountIdValue, accountIdOperation } from "./accountId";
import { ButtonValue, buttonOperation } from "./button";
import { IdValue, idOperation } from "./id";
import { ImageValue, imageOperation } from "./image";
import { ListSelection, ListValue, listOperation } from "./list";
import { MultiLineTextValue, multiLineTextOperation } from "./multiLineText";
import { NumberValue, numberOperation } from "./number";
import { OneLineTextValue, oneLineTextOperation } from "./oneLineText";
import { ProductSelection, ProductValue, productOperation } from "./product";
import { ProjectIdValue, projectIdOperation } from "./projectId";
import { SumSelection, SumValue, sumOperation } from "./sum";
import { TimeValue, timeOperation } from "./time";
import {
TypePartIdSelection,
TypePartIdValue,
typePartIdOperation,
} from "./typePartId";
import { TypeSelection, TypeValue, typeOperation } from "./type";
import type { ElementOperation } from "./ElementOperation";
import { maybeMap } from "../../common/util";
export type CommonSelection =
| {
readonly tag: "product";
readonly productSelection: ProductSelection;
}
| {
readonly tag: "list";
readonly listSelection: ListSelection;
}
| {
readonly tag: "sum";
readonly sumSelection: SumSelection;
}
| {
readonly tag: "typePartId";
readonly typePartIdSelection: TypePartIdSelection;
}
| {
readonly tag: "type";
readonly typeSelection: TypeSelection;
};
const selectionProduct = (value: ProductSelection): CommonSelection => ({
tag: "product",
productSelection: value,
});
const selectionList = (value: ListSelection): CommonSelection => ({
tag: "list",
listSelection: value,
});
const selectionSum = (sumSelection: SumSelection): CommonSelection => ({
tag: "sum",
sumSelection,
});
const selectionType = (typeSelection: TypeSelection): CommonSelection => ({
tag: "type",
typeSelection,
});
export type CommonValue =
| {
readonly type: "oneLineText";
readonly value: OneLineTextValue;
}
| {
readonly type: "multiLineText";
readonly value: MultiLineTextValue;
}
| {
readonly type: "number";
readonly value: NumberValue;
}
| {
readonly type: "sum";
readonly value: SumValue;
}
| {
readonly type: "accountId";
readonly value: AccountIdValue;
}
| {
readonly type: "time";
readonly value: TimeValue;
}
| {
readonly type: "list";
readonly value: ListValue;
}
| {
readonly type: "product";
readonly value: ProductValue;
}
| {
readonly type: "image";
readonly value: ImageValue;
}
| {
readonly type: "projectId";
readonly value: ProjectIdValue;
}
| {
readonly type: "typePartId";
readonly value: TypePartIdValue;
}
| {
readonly type: "button";
readonly value: ButtonValue;
}
| {
readonly type: "type";
readonly value: TypeValue;
}
| {
readonly type: "id";
readonly value: IdValue;
};
export const oneLineTextValue = (value: OneLineTextValue): CommonValue => ({
type: "oneLineText",
value,
});
export const multiLineTextValue = (value: MultiLineTextValue): CommonValue => ({
type: "multiLineText",
value,
});
export const numberValue = (value: NumberValue): CommonValue => ({
type: "number",
value,
});
export const sumValue = (value: SumValue): CommonValue => ({
type: "sum",
value,
});
export const accountIdValue = (value: AccountIdValue): CommonValue => ({
type: "accountId",
value,
});
export const timeValue = (value: TimeValue): CommonValue => ({
type: "time",
value,
});
export const listValue = (value: ListValue): CommonValue => ({
type: "list",
value,
});
export const productValue = (value: ProductValue): CommonValue => ({
type: "product",
value,
});
export const imageValue = (value: ImageValue): CommonValue => ({
type: "image",
value,
});
export const projectIdValue = (value: ProjectIdValue): CommonValue => ({
type: "projectId",
value,
});
export const typePartIdValue = (value: TypePartIdValue): CommonValue => ({
type: "typePartId",
value,
});
export const buttonValue = (value: ButtonValue): CommonValue => ({
type: "button",
value,
});
export const typeValue = (value: TypeValue): CommonValue => ({
type: "type",
value,
});
export const idValue = (value: IdValue): CommonValue => ({
type: "id",
value,
});
const moveUp = (
selection: CommonSelection,
value: CommonValue
): CommonSelection => {
if (selection.tag === "list" && value.type === "list") {
return selectionList(
listOperation.moveUp(selection.listSelection, value.value)
);
}
if (selection.tag === "product" && value.type === "product") {
return selectionProduct(
productOperation.moveUp(selection.productSelection, value.value)
);
}
if (selection.tag === "sum" && value.type === "sum") {
return selectionSum(
sumOperation.moveUp(selection.sumSelection, value.value)
);
}
return selection;
};
const moveDown = (
selection: CommonSelection,
value: CommonValue
): CommonSelection => {
if (selection.tag === "list" && value.type === "list") {
return selectionList(
listOperation.moveDown(selection.listSelection, value.value)
);
}
if (selection.tag === "product" && value.type === "product") {
return selectionProduct(
productOperation.moveDown(selection.productSelection, value.value)
);
}
if (selection.tag === "sum" && value.type === "sum") {
return selectionSum(
sumOperation.moveDown(selection.sumSelection, value.value)
);
}
return selection;
};
const moveFirstChild = (
selection: CommonSelection | undefined,
value: CommonValue
): CommonSelection | undefined => {
switch (value.type) {
case "list":
return maybeMap(
listOperation.moveFirstChild(
selection !== undefined && selection.tag === "list"
? selection.listSelection
: undefined,
value.value
),
selectionList
);
case "product":
return maybeMap(
productOperation.moveFirstChild(
selection !== undefined && selection.tag === "product"
? selection.productSelection
: undefined,
value.value
),
selectionProduct
);
case "sum":
return maybeMap(
sumOperation.moveFirstChild(
selection !== undefined && selection.tag === "sum"
? selection.sumSelection
: undefined,
value.value
),
selectionSum
);
}
};
const moveParent: ElementOperation<
CommonSelection,
CommonValue
>["moveParent"] = (selection, value) => {
if (selection.tag === "list" && value.type === "list") {
return maybeMap(
listOperation.moveParent(selection.listSelection, value.value),
selectionList
);
}
if (selection.tag === "product" && value.type === "product") {
return maybeMap(
productOperation.moveParent(selection.productSelection, value.value),
selectionProduct
);
}
if (selection.tag === "sum" && value.type === "sum") {
return maybeMap(
sumOperation.moveParent(selection.sumSelection, value.value),
selectionSum
);
}
};
const noSelectionDummyFunction = () => {};
const CommonElementSelectionView: ElementOperation<
CommonSelection,
CommonValue
>["selectionView"] = React.memo((props) => {
const onChangeSelection = props.onChangeSelection;
const sumChangeSelection = React.useCallback(
(s: SumSelection): void => onChangeSelection(selectionSum(s)),
[onChangeSelection]
);
const listChangeSelection = React.useCallback(
(listSelection: ListSelection): void =>
onChangeSelection(selectionList(listSelection)),
[onChangeSelection]
);
const productChangeSelection = React.useCallback(
(productSelection: ProductSelection): void =>
onChangeSelection(selectionProduct(productSelection)),
[onChangeSelection]
);
const typeChangeSelection = React.useCallback(
(selection: TypeSelection): void =>
onChangeSelection(selectionType(selection)),
[onChangeSelection]
);
switch (props.value.type) {
case "number":
return (
);
case "oneLineText":
return (
);
case "multiLineText":
return (
);
case "sum":
return (
);
case "image":
return (
);
case "accountId":
return (
);
case "time":
return (
);
case "projectId":
return (
);
case "list":
return (
);
case "product":
return (
);
case "typePartId":
return (
);
case "button":
return (
);
case "type":
return (
);
case "id":
return (
);
}
});
CommonElementSelectionView.displayName = "CommonElementSelectionView";
const CommonElementDetailView: ElementOperation<
CommonSelection,
CommonValue
>["detailView"] = React.memo((props) => {
switch (props.value.type) {
case "number":
return (
);
case "oneLineText":
return (
);
case "multiLineText":
return (
);
case "sum":
return (
);
case "image":
return (
);
case "accountId":
return (
);
case "projectId":
return (
);
case "time":
return (
);
case "list":
return (
);
case "product":
return (
);
case "typePartId":
return (
);
case "button":
return (
);
case "type":
return (
);
case "id":
return (
);
}
});
CommonElementDetailView.displayName = "CommonElementDetailView";
export const commonElement: ElementOperation = {
moveUp,
moveDown,
moveFirstChild,
moveParent,
selectionView: CommonElementSelectionView,
detailView: CommonElementDetailView,
};