Skip to content

Commit

Permalink
Merge branch 'main' into chore-server/items-as-csv-to-usecase
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkarel authored Dec 10, 2024
2 parents e66d212 + 7d6b287 commit 744091d
Show file tree
Hide file tree
Showing 28 changed files with 248 additions and 90 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build_worker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ jobs:
- name: Build and push docker image
uses: docker/build-push-action@v6
with:
context: ./worker
context: .
file: ./worker/Dockerfile
platforms: ${{ steps.options.outputs.platforms }}
push: true
build-args: VERSION=${{ steps.options.outputs.version }}
Expand Down
3 changes: 1 addition & 2 deletions web/e2e/project/item/fields/markdown.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ test("Markdown field editing has succeeded", async ({ page }) => {
await page.getByRole("button", { name: "delete" }).first().click();
await expect(page.getByText("Please input field!")).toBeVisible();
await page.getByRole("button", { name: "plus New" }).click();
await page.getByRole("button", { name: "Save" }).click();
await closeNotification(page, false);
await expect(page.getByRole("button", { name: "Save" })).toBeDisabled();
await page.locator("div:nth-child(1) > .css-1ago99h").click();
await page.getByRole("textbox").fill("text");
await page.getByRole("button", { name: "plus New" }).click();
Expand Down
3 changes: 1 addition & 2 deletions web/e2e/project/item/fields/text.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ test("Text field editing has succeeded", async ({ page }) => {
await expect(page.getByText("Please input field!")).toBeVisible();
await page.getByRole("button", { name: "plus New" }).click();
await expect(page.getByText("/ 5")).toBeVisible();
await page.getByRole("button", { name: "Save" }).click();
await closeNotification(page, false);
await expect(page.getByRole("button", { name: "Save" })).toBeDisabled();
await page.getByRole("textbox").nth(0).click();
await page.getByRole("textbox").nth(0).fill("text");
await page.getByRole("button", { name: "plus New" }).click();
Expand Down
3 changes: 1 addition & 2 deletions web/e2e/project/item/fields/textarea.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ test("Textarea field editing has succeeded", async ({ page }) => {
await page.getByRole("button", { name: "delete" }).first().click();
await expect(page.getByText("Please input field!")).toBeVisible();
await page.getByRole("button", { name: "plus New" }).click();
await page.getByRole("button", { name: "Save" }).click();
await closeNotification(page, false);
await expect(page.getByRole("button", { name: "Save" })).toBeDisabled();
await page.getByRole("textbox").nth(0).click();
await page.getByRole("textbox").nth(0).fill("text");
await page.getByRole("button", { name: "plus New" }).click();
Expand Down
4 changes: 4 additions & 0 deletions web/e2e/project/item/metadata/text.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ test("Text metadata editing has succeeded", async ({ page }) => {
await expect(page.getByRole("main")).toContainText("new text1 description");
await expect(page.getByRole("textbox").nth(0)).toHaveValue("text2");
await expect(page.getByRole("textbox").nth(1)).toHaveValue("text1");
await page.getByLabel("new text1(unique)").click();
await page.getByLabel("new text1(unique)").fill("text22");
await expect(page.getByRole("button", { name: "Save" })).toBeDisabled();
await page.getByLabel("new text1(unique)").fill("text2");

await page.getByRole("button", { name: "Save" }).click();
await closeNotification(page);
Expand Down
3 changes: 2 additions & 1 deletion web/src/components/atoms/Form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Form, FormInstance } from "antd";
import { Rule } from "antd/lib/form";
import { Rule, RuleObject } from "antd/lib/form";
import { FormItemProps } from "antd/lib/form/FormItem";
import { FormItemLabelProps } from "antd/lib/form/FormItemLabel";
import { FieldError, ValidateErrorEntity } from "rc-field-form/lib/interface";
Expand All @@ -12,5 +12,6 @@ export type {
FieldError,
FormInstance,
Rule,
RuleObject,
ValidateErrorEntity,
};
44 changes: 25 additions & 19 deletions web/src/components/atoms/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,32 @@ type Props = {
isError?: boolean;
} & InputProps;

const Input = forwardRef<InputRef, Props>(({ value, isError, maxLength, ...props }, ref) => {
const status = useMemo(() => {
if (isError || (maxLength && value && runes(value).length > maxLength)) {
return "error";
}
}, [isError, maxLength, value]);
const Input = forwardRef<InputRef, Props>(
({ value, isError, maxLength, required, ...props }, ref) => {
const status = useMemo(() => {
if (
isError ||
(required && !value) ||
(maxLength && value && runes(value).length > maxLength)
) {
return "error";
}
}, [isError, maxLength, required, value]);

return (
<AntDInput
count={{
max: maxLength,
strategy: txt => runes(txt).length,
}}
value={value}
ref={ref}
status={status}
{...props}
/>
);
});
return (
<AntDInput
count={{
max: maxLength,
strategy: txt => runes(txt).length,
}}
value={value}
ref={ref}
status={status}
{...props}
/>
);
},
);

export default Input;
export type { InputProps };
14 changes: 10 additions & 4 deletions web/src/components/atoms/Markdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ import TextArea, { TextAreaProps } from "@reearth-cms/components/atoms/TextArea"
type Props = {
value?: string;
onChange?: (value: string) => void;
isError?: boolean;
} & TextAreaProps;

const MarkdownInput: React.FC<Props> = ({ value, onChange, ...props }) => {
const [showMD, setShowMD] = useState(true);
const textareaRef = useRef<HTMLInputElement>(null);
const isError = useMemo(
() => (props.maxLength && value ? runes(value).length > props.maxLength : false),
[props.maxLength, value],
);
const isError = useMemo(() => {
if (props.isError || (props.required && !value)) {
return true;
} else if (props.maxLength && value) {
return runes(value).length > props.maxLength;
} else {
return false;
}
}, [props, value]);

const handleBlur = useCallback((event: FocusEvent<HTMLTextAreaElement>) => {
event.stopPropagation();
Expand Down
45 changes: 26 additions & 19 deletions web/src/components/atoms/TextArea/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,35 @@ import { runes } from "runes2";

type Props = {
value?: string;
isError?: boolean;
} & TextAreaProps;

const TextArea = forwardRef<HTMLInputElement, Props>(({ value, maxLength, ...props }, ref) => {
const status = useMemo(() => {
if (maxLength && value && runes(value).length > maxLength) {
return "error";
}
}, [maxLength, value]);
const TextArea = forwardRef<HTMLInputElement, Props>(
({ value, isError, maxLength, required, ...props }, ref) => {
const status = useMemo(() => {
if (
isError ||
(required && !value) ||
(maxLength && value && runes(value).length > maxLength)
) {
return "error";
}
}, [required, isError, maxLength, value]);

return (
<AntTextArea
count={{
max: maxLength,
strategy: txt => runes(txt).length,
}}
value={value}
ref={ref}
status={status}
{...props}
/>
);
});
return (
<AntTextArea
count={{
max: maxLength,
strategy: txt => runes(txt).length,
}}
value={value}
ref={ref}
status={status}
{...props}
/>
);
},
);

export default TextArea;
export type { TextAreaProps };
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from "@reearth-cms/components/atoms/Button";
import Icon from "@reearth-cms/components/atoms/Icon";
import { InputProps } from "@reearth-cms/components/atoms/Input";
import { TextAreaProps } from "@reearth-cms/components/atoms/TextArea";
import { checkIfEmpty } from "@reearth-cms/components/molecules/Content/Form/fields/utils";
import { useT } from "@reearth-cms/i18n";

import { moveItemInArray } from "./moveItemArray";
Expand All @@ -26,6 +27,7 @@ const MultiValueField: React.FC<Props> = ({
onBlur,
FieldInput,
errorIndexes,
required,
...props
}) => {
const t = useT();
Expand Down Expand Up @@ -93,7 +95,7 @@ const MultiValueField: React.FC<Props> = ({
onChange={(e: ChangeEvent<HTMLInputElement>) => handleInput(e, key)}
onBlur={() => onBlur?.()}
value={valueItem}
isError={errorIndexes?.has(key)}
isError={(required && value.every(v => checkIfEmpty(v))) || errorIndexes?.has(key)}
/>
{!props.disabled && (
<FieldButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { ItemAsset } from "@reearth-cms/components/molecules/Content/types";
import { Field } from "@reearth-cms/components/molecules/Schema/types";
import { useT } from "@reearth-cms/i18n";

import { requiredValidator } from "../utils";

type AssetFieldProps = {
field: Field;
itemGroupId?: string;
Expand Down Expand Up @@ -74,6 +76,7 @@ const AssetField: React.FC<AssetFieldProps> = ({
rules={[
{
required: field.required,
validator: requiredValidator,
message: t("Please input field!"),
},
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Field } from "@reearth-cms/components/molecules/Schema/types";
import { useT } from "@reearth-cms/i18n";

import FieldTitle from "../../FieldTitle";
import { requiredValidator } from "../utils";

type DateFieldProps = {
field: Field;
Expand All @@ -24,6 +25,7 @@ const DateField: React.FC<DateFieldProps> = ({ field, itemGroupId, onMetaUpdate,
rules={[
{
required: field.required,
validator: requiredValidator,
message: t("Please input field!"),
},
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Field } from "@reearth-cms/components/molecules/Schema/types";
import { useT } from "@reearth-cms/i18n";

import FieldTitle from "../../FieldTitle";
import { requiredValidator } from "../utils";

type DefaultFieldProps = {
field: Field;
Expand All @@ -25,13 +26,16 @@ const DefaultField: React.FC<DefaultFieldProps> = ({
const t = useT();
const maxLength = useMemo(() => field.typeProperty?.maxLength, [field.typeProperty?.maxLength]);

const required = useMemo(() => field.required, [field.required]);

return (
<Form.Item
extra={field.description}
validateStatus="success"
rules={[
{
required: field.required,
required,
validator: requiredValidator,
message: t("Please input field!"),
},
{
Expand Down Expand Up @@ -59,9 +63,16 @@ const DefaultField: React.FC<DefaultFieldProps> = ({
maxLength={maxLength}
FieldInput={Input}
disabled={disabled}
required={required}
/>
) : (
<Input onBlur={onMetaUpdate} showCount={true} maxLength={maxLength} disabled={disabled} />
<Input
onBlur={onMetaUpdate}
showCount={true}
maxLength={maxLength}
disabled={disabled}
required={required}
/>
)}
</Form.Item>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Field } from "@reearth-cms/components/molecules/Schema/types";
import { useT } from "@reearth-cms/i18n";

import FieldTitle from "../../FieldTitle";
import { requiredValidator } from "../utils";

type DefaultFieldProps = {
field: Field;
Expand Down Expand Up @@ -39,6 +40,7 @@ const GeometryField: React.FC<DefaultFieldProps> = ({ field, itemGroupId, disabl
rules={[
{
required: field.required,
validator: requiredValidator,
message: t("Please input field!"),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Field } from "@reearth-cms/components/molecules/Schema/types";
import { useT } from "@reearth-cms/i18n";

import FieldTitle from "../../FieldTitle";
import { requiredValidator } from "../utils";

type DefaultFieldProps = {
field: Field;
Expand All @@ -19,13 +20,16 @@ const MarkdownField: React.FC<DefaultFieldProps> = ({ field, itemGroupId, disabl
const t = useT();
const maxLength = useMemo(() => field.typeProperty?.maxLength, [field.typeProperty?.maxLength]);

const required = useMemo(() => field.required, [field.required]);

return (
<Form.Item
extra={field.description}
validateStatus="success"
rules={[
{
required: field.required,
required,
validator: requiredValidator,
message: t("Please input field!"),
},
{
Expand All @@ -47,9 +51,14 @@ const MarkdownField: React.FC<DefaultFieldProps> = ({ field, itemGroupId, disabl
name={itemGroupId ? [field.id, itemGroupId] : field.id}
label={<FieldTitle title={field.title} isUnique={field.unique} isTitle={field.isTitle} />}>
{field.multiple ? (
<MultiValueField maxLength={maxLength} FieldInput={MarkdownInput} disabled={disabled} />
<MultiValueField
maxLength={maxLength}
FieldInput={MarkdownInput}
disabled={disabled}
required={required}
/>
) : (
<MarkdownInput maxLength={maxLength} disabled={disabled} />
<MarkdownInput maxLength={maxLength} disabled={disabled} required={required} />
)}
</Form.Item>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Field } from "@reearth-cms/components/molecules/Schema/types";
import { useT } from "@reearth-cms/i18n";

import FieldTitle from "../../FieldTitle";
import { requiredValidator } from "../utils";

type DefaultFieldProps = {
field: Field;
Expand Down Expand Up @@ -42,6 +43,7 @@ const NumberField: React.FC<DefaultFieldProps> = ({ field, itemGroupId, disabled
rules={[
{
required: field.required,
validator: requiredValidator,
message: t("Please input field!"),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Field } from "@reearth-cms/components/molecules/Schema/types";
import { useT } from "@reearth-cms/i18n";

import FieldTitle from "../../FieldTitle";
import { requiredValidator } from "../utils";

type DefaultFieldProps = {
field: Field;
Expand All @@ -24,6 +25,7 @@ const SelectField: React.FC<DefaultFieldProps> = ({ field, itemGroupId, disabled
rules={[
{
required: field.required,
validator: requiredValidator,
message: t("Please select an option!"),
},
]}>
Expand Down
Loading

0 comments on commit 744091d

Please sign in to comment.