Skip to content

Commit

Permalink
Merge branch 'main' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
reearth-bot committed Sep 27, 2023
2 parents 1741c2b + a742922 commit 326fe07
Show file tree
Hide file tree
Showing 55 changed files with 1,795 additions and 365 deletions.
27 changes: 27 additions & 0 deletions server/e2e/gql_nlslayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,33 @@ func TestNLSLayerCRUD(t *testing.T) {
Value("data").Object().
Value("value").Equal("secondSampleValue")

// Save current config before update
savedConfig := res3.Object().
Value("data").Object().
Value("node").Object().
Value("newLayers").Array().First().Object().
Value("config").Raw()

// Perform update with nil config
updateReq, _ := updateNLSLayer(e, layerId)
updateReq.Variables["config"] = nil
e.POST("/api/graphql").
WithHeader("Origin", "https://example.com").
WithHeader("X-Reearth-Debug-User", uID.String()).
WithHeader("Content-Type", "application/json").
WithJSON(updateReq).
Expect().
Status(http.StatusOK).
JSON()

// Fetch the layer again and compare the config with the saved config
_, res4 := fetchSceneForNewLayers(e, sId)
res4.Object().
Value("data").Object().
Value("node").Object().
Value("newLayers").Array().First().Object().
Value("config").Equal(savedConfig)

// Remove NLSLayer
_, _ = removeNLSLayer(e, layerId)
}
3 changes: 3 additions & 0 deletions server/internal/adapter/gql/gqlmodel/convert_nlslayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ func ToNLSLayerSimple(l *nlslayer.NLSLayerSimple) *NLSLayerSimple {
}

func ToNLSConfig(p JSON) *nlslayer.Config {
if p == nil {
return nil
}
co := make(nlslayer.Config)

for key, value := range p {
Expand Down
2 changes: 1 addition & 1 deletion web/src/beta/components/DragAndDropList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { styled } from "@reearth/services/theme";

import Item from "./Item";

type Props<Item extends { id: string } = { id: string }> = {
export type Props<Item extends { id: string } = { id: string }> = {
uniqueKey: string;
items: Item[];
getId: (item: Item) => string;
Expand Down
13 changes: 8 additions & 5 deletions web/src/beta/components/Slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ export type Props = {
max?: number;
} & ComponentProps<typeof SliderWithTooltip>;

const Slider: React.FC<Props> = ({ ...props }) => (
<SliderStyled disabled={props.disabled as boolean}>
<SliderWithTooltip {...props} />
</SliderStyled>
);
const Slider: React.FC<Props> = ({ ...props }) => {
const calculatedStep = props.step ? props.step : props.max ? props.max / 10 : 0.1;
return (
<SliderStyled disabled={props.disabled as boolean}>
<SliderWithTooltip step={calculatedStep} {...props} />
</SliderStyled>
);
};

const SliderStyled = styled.div<{ disabled: boolean }>`
width: 100%;
Expand Down
109 changes: 109 additions & 0 deletions web/src/beta/components/fields/ListField/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { useArgs } from "@storybook/preview-api";
import { Meta, StoryObj } from "@storybook/react";
import { useCallback } from "react";

import { styled } from "@reearth/services/theme";

import ListField, { Props } from ".";

const meta: Meta<typeof ListField> = {
component: ListField,
};

export default meta;

type Story = StoryObj<typeof ListField>;

export const Default: Story = (args: Props) => {
const [_, updateArgs] = useArgs();

const addItem = useCallback(() => {
const randomId = (Math.random() + 1).toString(36).substring(7);
updateArgs({
items: [
...args.items,
{
id: randomId,
value: `Item ${randomId}`,
},
],
});
}, [updateArgs, args.items]);

const removeItem = useCallback(
(key: string) => {
updateArgs({ items: args.items.filter(({ id }) => id != key) });
},
[updateArgs, args.items],
);

const onItemDrop = useCallback(
(item: { id: string; value: string }, index: number) => {
const items = [...args.items];
items.splice(
items.findIndex(x => x.id === item.id),
1,
);
items.splice(index, 0, item);
updateArgs({ items });
},
[updateArgs, args.items],
);

const onSelect = useCallback((id: string) => updateArgs({ selected: id }), [updateArgs]);

return (
<Wrapper>
<div>
<ListField
{...args}
addItem={addItem}
removeItem={removeItem}
onItemDrop={onItemDrop}
onSelect={onSelect}
/>
</div>
</Wrapper>
);
};

const Wrapper = styled.div`
display: flex;
flex-direction: column;
gap: 10%;
margin-left: 2rem;
margin-top: 2rem;
height: 300px;
width: 300px;
`;

Default.args = {
name: "List Field",
description: "List field Sample description",
items: [
{
id: "w3tlwi",
value: "Item w3tlwi",
},
{
id: "77eg5",
value: "Item 77eg5",
},
{
id: "7p218",
value: "Item 7p218",
},
{
id: "xquyo",
value: "Item xquyo",
},
{
id: "2mewj",
value: "Item 2mewj",
},
{
id: "d2gmu",
value: "Item d2gmu",
},
],
};
124 changes: 124 additions & 0 deletions web/src/beta/components/fields/ListField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { useCallback, useMemo } from "react";

import Button from "@reearth/beta/components/Button";
import DragAndDropList, {
Props as DragAndDropProps,
} from "@reearth/beta/components/DragAndDropList";
import Property from "@reearth/beta/components/fields";
import Text from "@reearth/beta/components/Text";
import { useT } from "@reearth/services/i18n";
import { styled } from "@reearth/services/theme";

type ListItem = {
id: string;
value: string;
};

export type Props = {
name?: string;
description?: string;
items: ListItem[];
removeItem: (id: string) => void;
addItem: () => void;
onSelect: (id: string) => void;
selected?: string;
} & Pick<DragAndDropProps, "onItemDrop">;

const ListField: React.FC<Props> = ({
name,
description,
items,
removeItem,
addItem,
onItemDrop,
onSelect,
selected,
}: Props) => {
const t = useT();

const deleteItem = useCallback(() => {
if (!selected) return;
removeItem(selected);
}, [selected, removeItem]);

const getId = useCallback(({ id }: ListItem) => {
return id;
}, []);

const disableRemoveButton = useMemo(() => {
if (!selected) return true;

return !items.find(({ id }) => id == selected);
}, [items, selected]);

return (
<Property name={name} description={description}>
<FieldWrapper>
<DragAndDropList<ListItem>
uniqueKey="ListField"
items={items}
onItemDrop={onItemDrop}
getId={getId}
renderItem={({ id, value }) => (
<Item onClick={() => onSelect(id)} selected={selected === id}>
<Text size="xFootnote">{value}</Text>
</Item>
)}
gap={0}
/>
</FieldWrapper>
<ButtonGroup>
<ButtonWrapper
onClick={deleteItem}
icon="trash"
buttonType="secondary"
text={t("Remove")}
size="medium"
disabled={disableRemoveButton}
/>
<ButtonWrapper
onClick={addItem}
icon="plus"
buttonType="secondary"
text={t("Add Item")}
size="medium"
/>
</ButtonGroup>
</Property>
);
};

const FieldWrapper = styled.div`
min-height: 84px;
max-height: 224px;
border-radius: 4px;
border: 1px solid rgba(77, 83, 88, 1);
overflow: auto;
`;

const Item = styled.div<{ selected: boolean }>`
display: flex;
align-items: center;
padding: 0 12px;
height: 28px;
cursor: pointer;
background: ${({ theme, selected }) => (selected ? theme.select.main : "inherit")};
&:hover {
background: ${({ theme, selected }) => (selected ? theme.select.main : theme.bg[2])};
}
`;

const ButtonGroup = styled.div`
display: flex;
gap: 4px;
`;

const ButtonWrapper = styled(Button)`
height: 28px;
width: 100%;
padding: 0px;
margin: 0px;
opacity: ${({ disabled }) => (disabled ? 0.6 : 1)};
`;

export default ListField;
38 changes: 27 additions & 11 deletions web/src/beta/components/fields/PropertyFields/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,41 @@ import { useCallback } from "react";
import { ValueType, ValueTypes } from "@reearth/beta/utils/value";
import { usePropertyFetcher } from "@reearth/services/api";

export default () => {
const { useUpdatePropertyValue } = usePropertyFetcher();
export default (propertyId: string, schemaGroup: string) => {
const { useUpdatePropertyValue, useAddPropertyItem, useRemovePropertyItem, useMovePropertyItem } =
usePropertyFetcher();

const handlePropertyValueUpdate = useCallback(
(
schemaGroupId: string,
propertyId: string,
fieldId: string,
vt: ValueType,
itemId?: string,
) => {
(fieldId: string, vt: ValueType, itemId?: string) => {
return async (v?: ValueTypes[ValueType]) => {
await useUpdatePropertyValue(propertyId, schemaGroupId, itemId, fieldId, "en", v, vt);
await useUpdatePropertyValue(propertyId, schemaGroup, itemId, fieldId, "en", v, vt);
};
},
[useUpdatePropertyValue],
[propertyId, schemaGroup, useUpdatePropertyValue],
);

const handleAddPropertyItem = useCallback(() => {
return useAddPropertyItem(propertyId, schemaGroup);
}, [propertyId, schemaGroup, useAddPropertyItem]);

const handleRemovePropertyItem = useCallback(
(itemId: string) => {
return useRemovePropertyItem(propertyId, schemaGroup, itemId);
},
[propertyId, schemaGroup, useRemovePropertyItem],
);

const handleMovePropertyItem = useCallback(
({ id }: { id: string }, index: number) => {
return useMovePropertyItem(propertyId, schemaGroup, id, index);
},
[propertyId, schemaGroup, useMovePropertyItem],
);

return {
handlePropertyValueUpdate,
handleAddPropertyItem,
handleRemovePropertyItem,
handleMovePropertyItem,
};
};
Loading

0 comments on commit 326fe07

Please sign in to comment.