diff --git a/.github/workflows/ci_server.yml b/.github/workflows/ci_server.yml
index 5041479b9..e5862816e 100644
--- a/.github/workflows/ci_server.yml
+++ b/.github/workflows/ci_server.yml
@@ -15,6 +15,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
+ cache-dependency-path: server/go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
@@ -35,6 +36,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
+ cache-dependency-path: server/go.mod
- name: check forgotten translations
working-directory: server
run: make i18n-ci
@@ -53,6 +55,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
+ cache-dependency-path: server/go.mod
- name: test
run: go test ./... -v -race -coverprofile=coverage.txt -covermode=atomic -timeout 10m
working-directory: server
diff --git a/.github/workflows/ci_worker.yml b/.github/workflows/ci_worker.yml
index 158faf18c..6bc96bcea 100644
--- a/.github/workflows/ci_worker.yml
+++ b/.github/workflows/ci_worker.yml
@@ -14,6 +14,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
+ cache-dependency-path: worker/go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
@@ -36,6 +37,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
+ cache-dependency-path: worker/go.mod
- name: test
run: go test ./... -v -race -coverprofile=coverage.txt -covermode=atomic -timeout 10m
working-directory: worker
diff --git a/server/e2e/gql_field_test.go b/server/e2e/gql_field_test.go
index eb69ae270..309428b62 100644
--- a/server/e2e/gql_field_test.go
+++ b/server/e2e/gql_field_test.go
@@ -134,6 +134,7 @@ type fIds struct {
boolFId string
selectFId string
integerFId string
+ numberFId string
urlFId string
dateFId string
tagFID string
@@ -192,6 +193,16 @@ func createFieldOfEachType(t *testing.T, e *httpexpect.Expect, mId string) fIds
},
})
+ numberFId, _ := createField(e, mId, "number", "number", "number",
+ false, false, false, false, "Number",
+ map[string]any{
+ "number": map[string]any{
+ "defaultValue": nil,
+ "min": nil,
+ "max": nil,
+ },
+ })
+
urlFId, _ := createField(e, mId, "url", "url", "url",
false, false, false, false, "URL",
map[string]any{
@@ -260,6 +271,7 @@ func createFieldOfEachType(t *testing.T, e *httpexpect.Expect, mId string) fIds
boolFId,
selectFId,
integerFId,
+ numberFId,
urlFId,
dateFId,
tagFId,
@@ -276,6 +288,7 @@ func createFieldOfEachType(t *testing.T, e *httpexpect.Expect, mId string) fIds
boolFId: boolFId,
selectFId: selectFId,
integerFId: integerFId,
+ numberFId: numberFId,
urlFId: urlFId,
dateFId: dateFId,
tagFID: tagFId,
diff --git a/server/e2e/gql_item_test.go b/server/e2e/gql_item_test.go
index b1bbe7c31..935538208 100644
--- a/server/e2e/gql_item_test.go
+++ b/server/e2e/gql_item_test.go
@@ -412,7 +412,7 @@ func TestClearItemValues(t *testing.T) {
})
fields := r1.Path("$.data.createItem.item.fields[:].value").Raw().([]any)
assert.Equal(t, []any{
- "Text", "TextArea", "MarkdownText", aid.String(), true, "s1", float64(1), "https://www.1s.com", "2023-01-01T00:00:00Z", tagIds[0], true, "{\n\t\"type\": \"Point\",\n\t\"coordinates\": [102.0, 0.5]\n}", "{\n\t\"type\": \"Point\",\n\t\"coordinates\": [102.0, 0.5]\n}",
+ "Text", "TextArea", "MarkdownText", aid.String(), true, "s1", float64(1), nil, "https://www.1s.com", "2023-01-01T00:00:00Z", tagIds[0], true, "{\n\t\"type\": \"Point\",\n\t\"coordinates\": [102.0, 0.5]\n}", "{\n\t\"type\": \"Point\",\n\t\"coordinates\": [102.0, 0.5]\n}",
}, fields)
i1ver, _ := getItem(e, iid)
_, r2 := updateItem(e, iid, i1ver, []map[string]any{
@@ -432,7 +432,7 @@ func TestClearItemValues(t *testing.T) {
})
fields = r2.Path("$.data.updateItem.item.fields[:].value").Raw().([]any)
assert.Equal(t, []any{
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
}, fields)
iid2, _ := createItem(e, mId, sId, nil, []map[string]any{
@@ -453,7 +453,7 @@ func TestClearItemValues(t *testing.T) {
_, r3 := getItem(e, iid2)
fields2 := r3.Path("$.data.node.fields[:].value").Raw().([]any)
assert.Equal(t, []any{
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
}, fields2)
}
diff --git a/server/e2e/integration_item_test.go b/server/e2e/integration_item_test.go
index 773baf649..3feadddc3 100644
--- a/server/e2e/integration_item_test.go
+++ b/server/e2e/integration_item_test.go
@@ -1450,7 +1450,7 @@ func TestIntegrationModelImportJSONWithJsonInput(t *testing.T) {
mId, _ := createModel(e, pId, "test", "test", "test-1")
createFieldOfEachType(t, e, mId)
- jsonContent := `[{"text": "test1", "bool": true, "integer": 1},{"text": "test2", "bool": false, "integer": 2},{"text": "test3", "bool": null, "integer": null}]`
+ jsonContent := `[{"text": "test1", "bool": true, "number": 1.1},{"text": "test2", "bool": false, "number": 2},{"text": "test3", "bool": null, "number": null}]`
aId := UploadAsset(e, pId, "./test1.json", jsonContent).Object().Value("id").String().Raw()
res := IntegrationModelImportJSON(e, mId, aId, "json", "insert", false, nil)
res.Object().IsEqual(map[string]any{
@@ -1573,7 +1573,7 @@ func TestIntegrationItemsAsCSV(t *testing.T) {
})
res := IntegrationItemsAsCSV(e, mId, 1, 10, i1Id, "", "", nil)
- expected := fmt.Sprintf("id,location_lat,location_lng,text,textArea,markdown,asset,bool,select,integer,url,date,tag,checkbox\n%s,139.28179282584915,36.58570985749664,test1,,,,,,,,,,\n", i1Id)
+ expected := fmt.Sprintf("id,location_lat,location_lng,text,textArea,markdown,asset,bool,select,integer,number,url,date,tag,checkbox\n%s,139.28179282584915,36.58570985749664,test1,,,,,,,,,,,\n", i1Id)
res.IsEqual(expected)
}
@@ -1593,7 +1593,7 @@ func TestIntegrationItemsWithProjectAsCSV(t *testing.T) {
})
res := IntegrationItemsWithProjectAsCSV(e, pId, mId, 1, 10, i1Id, "", "", nil)
- expected := fmt.Sprintf("id,location_lat,location_lng,text,textArea,markdown,asset,bool,select,integer,url,date,tag,checkbox\n%s,139.28179282584915,36.58570985749664,test1,,,,,,30,,,,\n", i1Id)
+ expected := fmt.Sprintf("id,location_lat,location_lng,text,textArea,markdown,asset,bool,select,integer,number,url,date,tag,checkbox\n%s,139.28179282584915,36.58570985749664,test1,,,,,,30,,,,,\n", i1Id)
res.IsEqual(expected)
}
diff --git a/server/e2e/integration_schema_test.go b/server/e2e/integration_schema_test.go
index 4ba0a8ae9..04ecbf605 100644
--- a/server/e2e/integration_schema_test.go
+++ b/server/e2e/integration_schema_test.go
@@ -177,6 +177,52 @@ func TestIntegrationFieldCreateAPI(t *testing.T) {
res.ContainsKey("id")
+ res = e.GET("/api/models/{modelId}", mId1).
+ WithHeader("authorization", "Bearer "+secret).
+ Expect().
+ Status(http.StatusOK).
+ JSON().
+ Object()
+
+ res.ContainsSubset(map[string]any{
+ "name": "m1",
+ "id": mId1.String(),
+ "description": "m1 desc",
+ "public": true,
+ "key": ikey1.String(),
+ "projectId": pid,
+ "schemaId": sid1,
+ })
+
+ res.Value("createdAt").NotNull()
+ res.Value("updatedAt").NotNull()
+ res.Value("lastModified").NotNull()
+ resf := res.Value("schema").Object().Value("fields").Array()
+ resf.Length().IsEqual(3)
+ resf.Value(2).Object().ContainsSubset(map[string]any{
+ // "id": "", // generated
+ "key": "テスト",
+ "type": "text",
+ "required": false,
+ })
+ // endregion
+
+ //region bool
+ res = e.POST(endpoint, sid1).
+ WithHeader("authorization", "Bearer "+secret).
+ WithJSON(map[string]interface{}{
+ "key": "fKey1",
+ "type": "bool",
+ "multiple": false,
+ "required": false,
+ }).
+ Expect().
+ Status(http.StatusOK).
+ JSON().
+ Object()
+
+ res.ContainsKey("id")
+
res = e.GET("/api/models/{modelId}", mId1).
WithHeader("authorization", "Bearer "+secret).
Expect().
@@ -192,18 +238,25 @@ func TestIntegrationFieldCreateAPI(t *testing.T) {
HasValue("projectId", pid).
HasValue("schemaId", sid1)
- res.Value("schema").Object().Value("fields").Array().Length().IsEqual(3)
res.Value("createdAt").NotNull()
res.Value("updatedAt").NotNull()
res.Value("lastModified").NotNull()
+ resf = res.Value("schema").Object().Value("fields").Array()
+ resf.Length().IsEqual(4)
+ resf.Value(3).Object().ContainsSubset(map[string]any{
+ // "id": "", // generated
+ "key": "fKey1",
+ "type": "bool",
+ "required": false,
+ })
// endregion
- //region bool
+ //region number
res = e.POST(endpoint, sid1).
WithHeader("authorization", "Bearer "+secret).
WithJSON(map[string]interface{}{
- "key": "fKey1",
- "type": "bool",
+ "key": "fKey2",
+ "type": "number",
"multiple": false,
"required": false,
}).
@@ -229,17 +282,24 @@ func TestIntegrationFieldCreateAPI(t *testing.T) {
HasValue("projectId", pid).
HasValue("schemaId", sid1)
- res.Value("schema").Object().Value("fields").Array().Length().IsEqual(4)
res.Value("createdAt").NotNull()
res.Value("updatedAt").NotNull()
res.Value("lastModified").NotNull()
+ resf = res.Value("schema").Object().Value("fields").Array()
+ resf.Length().IsEqual(5)
+ resf.Value(4).Object().ContainsSubset(map[string]any{
+ // "id": "", // generated
+ "key": "fKey2",
+ "type": "number",
+ "required": false,
+ })
// endregion
// region GeoObject
res = e.POST(endpoint, sid1).
WithHeader("authorization", "Bearer "+secret).
WithJSON(map[string]interface{}{
- "key": "fKey2",
+ "key": "fKey3",
"type": "geometryObject",
"multiple": false,
"required": false,
diff --git a/server/internal/adapter/gql/generated.go b/server/internal/adapter/gql/generated.go
index 002574bcb..e9eda2b4e 100644
--- a/server/internal/adapter/gql/generated.go
+++ b/server/internal/adapter/gql/generated.go
@@ -688,6 +688,12 @@ type ComplexityRoot struct {
MaxLength func(childComplexity int) int
}
+ SchemaFieldNumber struct {
+ DefaultValue func(childComplexity int) int
+ Max func(childComplexity int) int
+ Min func(childComplexity int) int
+ }
+
SchemaFieldReference struct {
CorrespondingField func(childComplexity int) int
CorrespondingFieldID func(childComplexity int) int
@@ -4003,6 +4009,27 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.SchemaFieldMarkdown.MaxLength(childComplexity), true
+ case "SchemaFieldNumber.defaultValue":
+ if e.complexity.SchemaFieldNumber.DefaultValue == nil {
+ break
+ }
+
+ return e.complexity.SchemaFieldNumber.DefaultValue(childComplexity), true
+
+ case "SchemaFieldNumber.max":
+ if e.complexity.SchemaFieldNumber.Max == nil {
+ break
+ }
+
+ return e.complexity.SchemaFieldNumber.Max(childComplexity), true
+
+ case "SchemaFieldNumber.min":
+ if e.complexity.SchemaFieldNumber.Min == nil {
+ break
+ }
+
+ return e.complexity.SchemaFieldNumber.Min(childComplexity), true
+
case "SchemaFieldReference.correspondingField":
if e.complexity.SchemaFieldReference.CorrespondingField == nil {
break
@@ -4758,6 +4785,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
ec.unmarshalInputSchemaFieldGroupInput,
ec.unmarshalInputSchemaFieldIntegerInput,
ec.unmarshalInputSchemaFieldLineStringInput,
+ ec.unmarshalInputSchemaFieldNumberInput,
ec.unmarshalInputSchemaFieldReferenceInput,
ec.unmarshalInputSchemaFieldRichTextInput,
ec.unmarshalInputSchemaFieldSelectInput,
@@ -5159,6 +5187,7 @@ extend type Mutation {
Select
Tag
Integer
+ Number
Reference
Checkbox
URL
@@ -5231,6 +5260,7 @@ union SchemaFieldTypeProperty =
| SchemaFieldSelect
| SchemaFieldTag
| SchemaFieldInteger
+ | SchemaFieldNumber
| SchemaFieldReference
| SchemaFieldURL
| SchemaFieldCheckbox
@@ -5292,6 +5322,12 @@ type SchemaFieldInteger {
max: Int
}
+type SchemaFieldNumber {
+ defaultValue: Any
+ min: Float
+ max: Float
+}
+
type SchemaFieldReference {
modelId: ID!
schemaId: ID!
@@ -5382,6 +5418,12 @@ input SchemaFieldIntegerInput {
max: Int
}
+input SchemaFieldNumberInput {
+ defaultValue: Any
+ min: Float
+ max: Float
+}
+
input CorrespondingFieldInput {
fieldId: ID
title: String!
@@ -5430,6 +5472,7 @@ input SchemaFieldTypePropertyInput @onlyOne {
tag: SchemaFieldTagInput
checkbox: SchemaFieldCheckboxInput
integer: SchemaFieldIntegerInput
+ number: SchemaFieldNumberInput
reference: SchemaFieldReferenceInput
url: SchemaFieldURLInput
group: SchemaFieldGroupInput
@@ -6384,6 +6427,7 @@ input CreateRequestInput {
items: [RequestItemInput!]!
}
+
input UpdateRequestInput {
requestId: ID!
title: String
@@ -28701,6 +28745,129 @@ func (ec *executionContext) fieldContext_SchemaFieldMarkdown_maxLength(_ context
return fc, nil
}
+func (ec *executionContext) _SchemaFieldNumber_defaultValue(ctx context.Context, field graphql.CollectedField, obj *gqlmodel.SchemaFieldNumber) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_SchemaFieldNumber_defaultValue(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.DefaultValue, nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(any)
+ fc.Result = res
+ return ec.marshalOAny2interface(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_SchemaFieldNumber_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "SchemaFieldNumber",
+ Field: field,
+ IsMethod: false,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type Any does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) _SchemaFieldNumber_min(ctx context.Context, field graphql.CollectedField, obj *gqlmodel.SchemaFieldNumber) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_SchemaFieldNumber_min(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.Min, nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*float64)
+ fc.Result = res
+ return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_SchemaFieldNumber_min(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "SchemaFieldNumber",
+ Field: field,
+ IsMethod: false,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type Float does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) _SchemaFieldNumber_max(ctx context.Context, field graphql.CollectedField, obj *gqlmodel.SchemaFieldNumber) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_SchemaFieldNumber_max(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.Max, nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*float64)
+ fc.Result = res
+ return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_SchemaFieldNumber_max(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "SchemaFieldNumber",
+ Field: field,
+ IsMethod: false,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type Float does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
func (ec *executionContext) _SchemaFieldReference_modelId(ctx context.Context, field graphql.CollectedField, obj *gqlmodel.SchemaFieldReference) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SchemaFieldReference_modelId(ctx, field)
if err != nil {
@@ -38185,6 +38352,47 @@ func (ec *executionContext) unmarshalInputSchemaFieldLineStringInput(ctx context
return it, nil
}
+func (ec *executionContext) unmarshalInputSchemaFieldNumberInput(ctx context.Context, obj interface{}) (gqlmodel.SchemaFieldNumberInput, error) {
+ var it gqlmodel.SchemaFieldNumberInput
+ asMap := map[string]interface{}{}
+ for k, v := range obj.(map[string]interface{}) {
+ asMap[k] = v
+ }
+
+ fieldsInOrder := [...]string{"defaultValue", "min", "max"}
+ for _, k := range fieldsInOrder {
+ v, ok := asMap[k]
+ if !ok {
+ continue
+ }
+ switch k {
+ case "defaultValue":
+ ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("defaultValue"))
+ data, err := ec.unmarshalOAny2interface(ctx, v)
+ if err != nil {
+ return it, err
+ }
+ it.DefaultValue = data
+ case "min":
+ ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("min"))
+ data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v)
+ if err != nil {
+ return it, err
+ }
+ it.Min = data
+ case "max":
+ ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("max"))
+ data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v)
+ if err != nil {
+ return it, err
+ }
+ it.Max = data
+ }
+ }
+
+ return it, nil
+}
+
func (ec *executionContext) unmarshalInputSchemaFieldReferenceInput(ctx context.Context, obj interface{}) (gqlmodel.SchemaFieldReferenceInput, error) {
var it gqlmodel.SchemaFieldReferenceInput
asMap := map[string]interface{}{}
@@ -38444,7 +38652,7 @@ func (ec *executionContext) unmarshalInputSchemaFieldTypePropertyInput(ctx conte
asMap[k] = v
}
- fieldsInOrder := [...]string{"text", "textArea", "richText", "markdownText", "asset", "date", "bool", "select", "tag", "checkbox", "integer", "reference", "url", "group", "geometryObject", "geometryEditor"}
+ fieldsInOrder := [...]string{"text", "textArea", "richText", "markdownText", "asset", "date", "bool", "select", "tag", "checkbox", "integer", "number", "reference", "url", "group", "geometryObject", "geometryEditor"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -38737,6 +38945,32 @@ func (ec *executionContext) unmarshalInputSchemaFieldTypePropertyInput(ctx conte
err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/reearth/reearth-cms/server/internal/adapter/gql/gqlmodel.SchemaFieldIntegerInput`, tmp)
return it, graphql.ErrorOnPath(ctx, err)
}
+ case "number":
+ ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("number"))
+ directive0 := func(ctx context.Context) (interface{}, error) {
+ return ec.unmarshalOSchemaFieldNumberInput2ᚖgithubᚗcomᚋreearthᚋreearthᚑcmsᚋserverᚋinternalᚋadapterᚋgqlᚋgqlmodelᚐSchemaFieldNumberInput(ctx, v)
+ }
+
+ directive1 := func(ctx context.Context) (interface{}, error) {
+ if ec.directives.OnlyOne == nil {
+ var zeroVal *gqlmodel.SchemaFieldNumberInput
+ return zeroVal, errors.New("directive onlyOne is not implemented")
+ }
+ return ec.directives.OnlyOne(ctx, obj, directive0)
+ }
+
+ tmp, err := directive1(ctx)
+ if err != nil {
+ return it, graphql.ErrorOnPath(ctx, err)
+ }
+ if data, ok := tmp.(*gqlmodel.SchemaFieldNumberInput); ok {
+ it.Number = data
+ } else if tmp == nil {
+ it.Number = nil
+ } else {
+ err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/reearth/reearth-cms/server/internal/adapter/gql/gqlmodel.SchemaFieldNumberInput`, tmp)
+ return it, graphql.ErrorOnPath(ctx, err)
+ }
case "reference":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reference"))
directive0 := func(ctx context.Context) (interface{}, error) {
@@ -40644,6 +40878,13 @@ func (ec *executionContext) _SchemaFieldTypeProperty(ctx context.Context, sel as
return graphql.Null
}
return ec._SchemaFieldInteger(ctx, sel, obj)
+ case gqlmodel.SchemaFieldNumber:
+ return ec._SchemaFieldNumber(ctx, sel, &obj)
+ case *gqlmodel.SchemaFieldNumber:
+ if obj == nil {
+ return graphql.Null
+ }
+ return ec._SchemaFieldNumber(ctx, sel, obj)
case gqlmodel.SchemaFieldReference:
return ec._SchemaFieldReference(ctx, sel, &obj)
case *gqlmodel.SchemaFieldReference:
@@ -46592,6 +46833,46 @@ func (ec *executionContext) _SchemaFieldMarkdown(ctx context.Context, sel ast.Se
return out
}
+var schemaFieldNumberImplementors = []string{"SchemaFieldNumber", "SchemaFieldTypeProperty"}
+
+func (ec *executionContext) _SchemaFieldNumber(ctx context.Context, sel ast.SelectionSet, obj *gqlmodel.SchemaFieldNumber) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.OperationContext, sel, schemaFieldNumberImplementors)
+
+ out := graphql.NewFieldSet(fields)
+ deferred := make(map[string]*graphql.FieldSet)
+ for i, field := range fields {
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("SchemaFieldNumber")
+ case "defaultValue":
+ out.Values[i] = ec._SchemaFieldNumber_defaultValue(ctx, field, obj)
+ case "min":
+ out.Values[i] = ec._SchemaFieldNumber_min(ctx, field, obj)
+ case "max":
+ out.Values[i] = ec._SchemaFieldNumber_max(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+ out.Dispatch(ctx)
+ if out.Invalids > 0 {
+ return graphql.Null
+ }
+
+ atomic.AddInt32(&ec.deferred, int32(len(deferred)))
+
+ for label, dfs := range deferred {
+ ec.processDeferredGroup(graphql.DeferredGroup{
+ Label: label,
+ Path: graphql.GetPath(ctx),
+ FieldSet: dfs,
+ Context: ctx,
+ })
+ }
+
+ return out
+}
+
var schemaFieldReferenceImplementors = []string{"SchemaFieldReference", "SchemaFieldTypeProperty"}
func (ec *executionContext) _SchemaFieldReference(ctx context.Context, sel ast.SelectionSet, obj *gqlmodel.SchemaFieldReference) graphql.Marshaler {
@@ -52132,6 +52413,22 @@ func (ec *executionContext) marshalOFieldsPayload2ᚖgithubᚗcomᚋreearthᚋre
return ec._FieldsPayload(ctx, sel, v)
}
+func (ec *executionContext) unmarshalOFloat2ᚖfloat64(ctx context.Context, v interface{}) (*float64, error) {
+ if v == nil {
+ return nil, nil
+ }
+ res, err := graphql.UnmarshalFloatContext(ctx, v)
+ return &res, graphql.ErrorOnPath(ctx, err)
+}
+
+func (ec *executionContext) marshalOFloat2ᚖfloat64(ctx context.Context, sel ast.SelectionSet, v *float64) graphql.Marshaler {
+ if v == nil {
+ return graphql.Null
+ }
+ res := graphql.MarshalFloatContext(*v)
+ return graphql.WrapContextMarshaler(ctx, res)
+}
+
func (ec *executionContext) marshalOGroup2ᚖgithubᚗcomᚋreearthᚋreearthᚑcmsᚋserverᚋinternalᚋadapterᚋgqlᚋgqlmodelᚐGroup(ctx context.Context, sel ast.SelectionSet, v *gqlmodel.Group) graphql.Marshaler {
if v == nil {
return graphql.Null
@@ -52849,6 +53146,14 @@ func (ec *executionContext) unmarshalOSchemaFieldIntegerInput2ᚖgithubᚗcomᚋ
return &res, graphql.ErrorOnPath(ctx, err)
}
+func (ec *executionContext) unmarshalOSchemaFieldNumberInput2ᚖgithubᚗcomᚋreearthᚋreearthᚑcmsᚋserverᚋinternalᚋadapterᚋgqlᚋgqlmodelᚐSchemaFieldNumberInput(ctx context.Context, v interface{}) (*gqlmodel.SchemaFieldNumberInput, error) {
+ if v == nil {
+ return nil, nil
+ }
+ res, err := ec.unmarshalInputSchemaFieldNumberInput(ctx, v)
+ return &res, graphql.ErrorOnPath(ctx, err)
+}
+
func (ec *executionContext) unmarshalOSchemaFieldReferenceInput2ᚖgithubᚗcomᚋreearthᚋreearthᚑcmsᚋserverᚋinternalᚋadapterᚋgqlᚋgqlmodelᚐSchemaFieldReferenceInput(ctx context.Context, v interface{}) (*gqlmodel.SchemaFieldReferenceInput, error) {
if v == nil {
return nil, nil
diff --git a/server/internal/adapter/gql/gqlmodel/convert_schema.go b/server/internal/adapter/gql/gqlmodel/convert_schema.go
index f3d5312ad..3948c193c 100644
--- a/server/internal/adapter/gql/gqlmodel/convert_schema.go
+++ b/server/internal/adapter/gql/gqlmodel/convert_schema.go
@@ -268,10 +268,10 @@ func ToSchemaFieldTypeProperty(tp *schema.TypeProperty, dv *value.Multiple, mult
v, _ = dv.First().ValueNumber()
}
}
- res = &SchemaFieldInteger{
+ res = &SchemaFieldNumber{
DefaultValue: v,
- Min: util.ToPtrIfNotEmpty(int(lo.FromPtr(f.Min()))),
- Max: util.ToPtrIfNotEmpty(int(lo.FromPtr(f.Max()))),
+ Min: util.ToPtrIfNotEmpty(float64(lo.FromPtr(f.Min()))),
+ Max: util.ToPtrIfNotEmpty(float64(lo.FromPtr(f.Max()))),
}
},
Integer: func(f *schema.FieldInteger) {
@@ -556,6 +556,28 @@ func FromSchemaTypeProperty(tp *SchemaFieldTypePropertyInput, t SchemaFieldType,
err = err2
}
tpRes = tpi.TypeProperty()
+ case SchemaFieldTypeNumber:
+ x := tp.Number
+ if x == nil {
+ return nil, nil, ErrInvalidTypeProperty
+ }
+ if multiple {
+ dv = value.NewMultiple(value.TypeNumber, unpackArray(x.DefaultValue))
+ } else {
+ dv = FromValue(SchemaFieldTypeNumber, x.DefaultValue).AsMultiple()
+ }
+ var min, max *float64
+ if x.Min != nil {
+ min = lo.ToPtr(float64(*x.Min))
+ }
+ if x.Max != nil {
+ max = lo.ToPtr(float64(*x.Max))
+ }
+ tpi, err2 := schema.NewNumber(min, max)
+ if err2 != nil {
+ err = err2
+ }
+ tpRes = tpi.TypeProperty()
case SchemaFieldTypeReference:
x := tp.Reference
if x == nil {
diff --git a/server/internal/adapter/gql/gqlmodel/convert_value.go b/server/internal/adapter/gql/gqlmodel/convert_value.go
index 0af3e0331..00c6f69df 100644
--- a/server/internal/adapter/gql/gqlmodel/convert_value.go
+++ b/server/internal/adapter/gql/gqlmodel/convert_value.go
@@ -25,7 +25,7 @@ func ToValueType(t value.Type) SchemaFieldType {
case value.TypeSelect:
return SchemaFieldTypeSelect
case value.TypeNumber:
- return SchemaFieldTypeInteger
+ return SchemaFieldTypeNumber
case value.TypeInteger:
return SchemaFieldTypeInteger
case value.TypeReference:
@@ -69,6 +69,8 @@ func FromValueType(t SchemaFieldType) value.Type {
return value.TypeCheckbox
case SchemaFieldTypeInteger:
return value.TypeInteger
+ case SchemaFieldTypeNumber:
+ return value.TypeNumber
case SchemaFieldTypeReference:
return value.TypeReference
case SchemaFieldTypeURL:
diff --git a/server/internal/adapter/gql/gqlmodel/models_gen.go b/server/internal/adapter/gql/gqlmodel/models_gen.go
index c584fef54..4c2e33e31 100644
--- a/server/internal/adapter/gql/gqlmodel/models_gen.go
+++ b/server/internal/adapter/gql/gqlmodel/models_gen.go
@@ -1030,6 +1030,20 @@ type SchemaFieldMarkdown struct {
func (SchemaFieldMarkdown) IsSchemaFieldTypeProperty() {}
+type SchemaFieldNumber struct {
+ DefaultValue any `json:"defaultValue,omitempty"`
+ Min *float64 `json:"min,omitempty"`
+ Max *float64 `json:"max,omitempty"`
+}
+
+func (SchemaFieldNumber) IsSchemaFieldTypeProperty() {}
+
+type SchemaFieldNumberInput struct {
+ DefaultValue any `json:"defaultValue,omitempty"`
+ Min *float64 `json:"min,omitempty"`
+ Max *float64 `json:"max,omitempty"`
+}
+
type SchemaFieldReference struct {
ModelID ID `json:"modelId"`
SchemaID ID `json:"schemaId"`
@@ -1130,6 +1144,7 @@ type SchemaFieldTypePropertyInput struct {
Tag *SchemaFieldTagInput `json:"tag,omitempty"`
Checkbox *SchemaFieldCheckboxInput `json:"checkbox,omitempty"`
Integer *SchemaFieldIntegerInput `json:"integer,omitempty"`
+ Number *SchemaFieldNumberInput `json:"number,omitempty"`
Reference *SchemaFieldReferenceInput `json:"reference,omitempty"`
URL *SchemaFieldURLInput `json:"url,omitempty"`
Group *SchemaFieldGroupInput `json:"group,omitempty"`
@@ -2430,6 +2445,7 @@ const (
SchemaFieldTypeSelect SchemaFieldType = "Select"
SchemaFieldTypeTag SchemaFieldType = "Tag"
SchemaFieldTypeInteger SchemaFieldType = "Integer"
+ SchemaFieldTypeNumber SchemaFieldType = "Number"
SchemaFieldTypeReference SchemaFieldType = "Reference"
SchemaFieldTypeCheckbox SchemaFieldType = "Checkbox"
SchemaFieldTypeURL SchemaFieldType = "URL"
@@ -2449,6 +2465,7 @@ var AllSchemaFieldType = []SchemaFieldType{
SchemaFieldTypeSelect,
SchemaFieldTypeTag,
SchemaFieldTypeInteger,
+ SchemaFieldTypeNumber,
SchemaFieldTypeReference,
SchemaFieldTypeCheckbox,
SchemaFieldTypeURL,
@@ -2459,7 +2476,7 @@ var AllSchemaFieldType = []SchemaFieldType{
func (e SchemaFieldType) IsValid() bool {
switch e {
- case SchemaFieldTypeText, SchemaFieldTypeTextArea, SchemaFieldTypeRichText, SchemaFieldTypeMarkdownText, SchemaFieldTypeAsset, SchemaFieldTypeDate, SchemaFieldTypeBool, SchemaFieldTypeSelect, SchemaFieldTypeTag, SchemaFieldTypeInteger, SchemaFieldTypeReference, SchemaFieldTypeCheckbox, SchemaFieldTypeURL, SchemaFieldTypeGroup, SchemaFieldTypeGeometryObject, SchemaFieldTypeGeometryEditor:
+ case SchemaFieldTypeText, SchemaFieldTypeTextArea, SchemaFieldTypeRichText, SchemaFieldTypeMarkdownText, SchemaFieldTypeAsset, SchemaFieldTypeDate, SchemaFieldTypeBool, SchemaFieldTypeSelect, SchemaFieldTypeTag, SchemaFieldTypeInteger, SchemaFieldTypeNumber, SchemaFieldTypeReference, SchemaFieldTypeCheckbox, SchemaFieldTypeURL, SchemaFieldTypeGroup, SchemaFieldTypeGeometryObject, SchemaFieldTypeGeometryEditor:
return true
}
return false
diff --git a/server/internal/adapter/gql/resolver_workspace.go b/server/internal/adapter/gql/resolver_workspace.go
index 9770358e6..c795a0683 100644
--- a/server/internal/adapter/gql/resolver_workspace.go
+++ b/server/internal/adapter/gql/resolver_workspace.go
@@ -6,11 +6,13 @@ package gql
import (
"context"
+ "errors"
"github.com/reearth/reearth-cms/server/internal/adapter/gql/gqlmodel"
"github.com/reearth/reearth-cms/server/internal/usecase/interfaces"
"github.com/reearth/reearthx/account/accountdomain"
"github.com/reearth/reearthx/account/accountdomain/workspace"
+ "github.com/reearth/reearthx/rerror"
)
// CreateWorkspace is the resolver for the createWorkspace field.
@@ -37,9 +39,8 @@ func (r *mutationResolver) DeleteWorkspace(ctx context.Context, input gqlmodel.D
return nil, err
}
- if err := usecases(ctx).WorkspaceSettings.Delete(ctx, interfaces.DeleteWorkspaceSettingsParam{
- ID: wid,
- }, getOperator(ctx)); err != nil {
+ err = usecases(ctx).WorkspaceSettings.Delete(ctx, interfaces.DeleteWorkspaceSettingsParam{ID: wid}, getOperator(ctx))
+ if err != nil && !errors.Is(err, rerror.ErrNotFound) {
return nil, err
}
diff --git a/server/internal/adapter/integration/item_import.go b/server/internal/adapter/integration/item_import.go
index 029656cf9..5fddfff1b 100644
--- a/server/internal/adapter/integration/item_import.go
+++ b/server/internal/adapter/integration/item_import.go
@@ -251,6 +251,10 @@ func isAssignable(vt1, vt2 value.Type) bool {
return true
}
if vt1 == value.TypeInteger &&
+ (vt2 == value.TypeText || vt2 == value.TypeRichText || vt2 == value.TypeMarkdown || vt2 == value.TypeNumber) {
+ return true
+ }
+ if vt1 == value.TypeNumber &&
(vt2 == value.TypeText || vt2 == value.TypeRichText || vt2 == value.TypeMarkdown) {
return true
}
@@ -282,7 +286,7 @@ func FieldFrom(k string, v any, sp schema.Package) interfaces.CreateFieldParam {
case reflect.Uint64:
case reflect.Float32:
case reflect.Float64:
- t = value.TypeInteger
+ t = value.TypeNumber
case reflect.String:
t = value.TypeText
default:
diff --git a/server/internal/adapter/integration/schema.go b/server/internal/adapter/integration/schema.go
index 01f7f630b..38741c00e 100644
--- a/server/internal/adapter/integration/schema.go
+++ b/server/internal/adapter/integration/schema.go
@@ -392,6 +392,9 @@ func FromSchemaTypeProperty(t integrationapi.ValueType, multiple bool) (tpRes *s
case integrationapi.ValueTypeInteger:
tpi, _ := schema.NewInteger(nil, nil)
tpRes = tpi.TypeProperty()
+ case integrationapi.ValueTypeNumber:
+ tpi, _ := schema.NewNumber(nil, nil)
+ tpRes = tpi.TypeProperty()
case integrationapi.ValueTypeReference:
if multiple {
return nil, nil, ErrMultipleReference
diff --git a/server/internal/adapter/integration/server.gen.go b/server/internal/adapter/integration/server.gen.go
index 5c4eb9a8a..03082bd41 100644
--- a/server/internal/adapter/integration/server.gen.go
+++ b/server/internal/adapter/integration/server.gen.go
@@ -4596,43 +4596,43 @@ var swaggerSpec = []string{
"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",
- "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",
+ "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",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/server/pkg/integrationapi/types.gen.go b/server/pkg/integrationapi/types.gen.go
index eaab7a4a8..bbfad53ec 100644
--- a/server/pkg/integrationapi/types.gen.go
+++ b/server/pkg/integrationapi/types.gen.go
@@ -163,6 +163,7 @@ const (
ValueTypeGroup ValueType = "group"
ValueTypeInteger ValueType = "integer"
ValueTypeMarkdown ValueType = "markdown"
+ ValueTypeNumber ValueType = "number"
ValueTypeReference ValueType = "reference"
ValueTypeRichText ValueType = "richText"
ValueTypeSelect ValueType = "select"
diff --git a/server/schemas/field.graphql b/server/schemas/field.graphql
index 9d2ac4be3..42b44308b 100644
--- a/server/schemas/field.graphql
+++ b/server/schemas/field.graphql
@@ -9,6 +9,7 @@ enum SchemaFieldType {
Select
Tag
Integer
+ Number
Reference
Checkbox
URL
@@ -81,6 +82,7 @@ union SchemaFieldTypeProperty =
| SchemaFieldSelect
| SchemaFieldTag
| SchemaFieldInteger
+ | SchemaFieldNumber
| SchemaFieldReference
| SchemaFieldURL
| SchemaFieldCheckbox
@@ -142,6 +144,12 @@ type SchemaFieldInteger {
max: Int
}
+type SchemaFieldNumber {
+ defaultValue: Any
+ min: Float
+ max: Float
+}
+
type SchemaFieldReference {
modelId: ID!
schemaId: ID!
@@ -232,6 +240,12 @@ input SchemaFieldIntegerInput {
max: Int
}
+input SchemaFieldNumberInput {
+ defaultValue: Any
+ min: Float
+ max: Float
+}
+
input CorrespondingFieldInput {
fieldId: ID
title: String!
@@ -280,6 +294,7 @@ input SchemaFieldTypePropertyInput @onlyOne {
tag: SchemaFieldTagInput
checkbox: SchemaFieldCheckboxInput
integer: SchemaFieldIntegerInput
+ number: SchemaFieldNumberInput
reference: SchemaFieldReferenceInput
url: SchemaFieldURLInput
group: SchemaFieldGroupInput
diff --git a/server/schemas/integration.yml b/server/schemas/integration.yml
index 4c00b8345..4b9d18775 100644
--- a/server/schemas/integration.yml
+++ b/server/schemas/integration.yml
@@ -1671,6 +1671,7 @@ components:
- bool
- select
- integer
+ - number
- reference
- url
- group
diff --git a/web/e2e/project/item/metadata/update.spec.ts b/web/e2e/project/item/metadata/update.spec.ts
index dd4bc777e..b901bd867 100644
--- a/web/e2e/project/item/metadata/update.spec.ts
+++ b/web/e2e/project/item/metadata/update.spec.ts
@@ -26,10 +26,12 @@ test.afterEach(async ({ page }) => {
});
test("Updating metadata added later from table has succeeded", async ({ page }) => {
+ await page.getByRole("switch").click();
+ await closeNotification(page);
await page.getByRole("switch").click();
await closeNotification(page);
await page.getByRole("cell").getByLabel("edit").locator("svg").click();
- await expect(page.getByLabel("boolean")).toHaveAttribute("aria-checked", "true");
+ await expect(page.getByLabel("boolean")).toHaveAttribute("aria-checked", "false");
});
test("Updating metadata added later from edit page has succeeded", async ({ page }) => {
diff --git a/web/src/components/atoms/Icon/Icons/arrowUpRightSlash.svg b/web/src/components/atoms/Icon/Icons/arrowUpRightSlash.svg
new file mode 100644
index 000000000..fafb0dfd5
--- /dev/null
+++ b/web/src/components/atoms/Icon/Icons/arrowUpRightSlash.svg
@@ -0,0 +1,3 @@
+
diff --git a/web/src/components/atoms/Icon/icons.ts b/web/src/components/atoms/Icon/icons.ts
index ba1edb677..ae9937386 100644
--- a/web/src/components/atoms/Icon/icons.ts
+++ b/web/src/components/atoms/Icon/icons.ts
@@ -51,10 +51,12 @@ import {
ReloadOutlined,
SortAscendingOutlined,
FilterOutlined,
+ CommentOutlined,
} from "@ant-design/icons";
import ArrowSquareOut from "./Icons/arrowSquareOut.svg";
import ArrowUpRight from "./Icons/arrowUpRight.svg";
+import ArrowUpRightSlash from "./Icons/arrowUpRightSlash.svg";
import Asset from "./Icons/asset.svg";
import Boolean from "./Icons/boolean.svg";
import CheckSquare from "./Icons/checkSquare.svg";
@@ -123,6 +125,7 @@ export default {
asset: Asset,
listBullets: ListBullets,
arrowUpRight: ArrowUpRight,
+ arrowUpRightSlash: ArrowUpRightSlash,
numberNine: NumberNine,
link: Link,
linkSolid: LinkSolid,
@@ -177,4 +180,5 @@ export default {
editorCopy: EditorCopy,
circle: Circle,
rectangle: Rectangle,
+ comment: CommentOutlined,
};
diff --git a/web/src/components/molecules/Asset/Asset/AssetBody/Asset.tsx b/web/src/components/molecules/Asset/Asset/AssetBody/Asset.tsx
index 023bbcfcd..ba11e35ff 100644
--- a/web/src/components/molecules/Asset/Asset/AssetBody/Asset.tsx
+++ b/web/src/components/molecules/Asset/Asset/AssetBody/Asset.tsx
@@ -223,6 +223,7 @@ const BodyContainer = styled.div`
flex-direction: row;
width: 100%;
height: calc(100% - 72px);
+ border-top: 1px solid #00000008;
.ant-tree-show-line .ant-tree-switcher {
background-color: transparent;
}
@@ -239,6 +240,7 @@ const BodyWrapper = styled.div`
const SideBarWrapper = styled.div`
padding: 8px;
width: 272px;
+ background-color: #fafafa;
`;
const StyledButton = styled(Button)`
diff --git a/web/src/components/molecules/Asset/Asset/AssetBody/sideBarCard.tsx b/web/src/components/molecules/Asset/Asset/AssetBody/sideBarCard.tsx
index 92ae23e3a..342b7a555 100644
--- a/web/src/components/molecules/Asset/Asset/AssetBody/sideBarCard.tsx
+++ b/web/src/components/molecules/Asset/Asset/AssetBody/sideBarCard.tsx
@@ -1,15 +1,14 @@
import styled from "@emotion/styled";
-import { CSSProperties, ReactNode } from "react";
+import { ReactNode } from "react";
type Props = {
title: string;
children?: ReactNode;
- style?: CSSProperties;
};
-const SideBarCard: React.FC = ({ title, children, style }) => {
+const SideBarCard: React.FC = ({ title, children }) => {
return (
-
+
{title}
{children}
@@ -23,6 +22,7 @@ const SideBarCardWrapper = styled.div`
display: flex;
flex-direction: column;
box-shadow: 0 4px 4px 0 #00000025;
+ background-color: #fff;
`;
const CardTitle = styled.span`
diff --git a/web/src/components/molecules/Asset/AssetList/index.tsx b/web/src/components/molecules/Asset/AssetList/index.tsx
index ecf86b343..cdf466f1f 100644
--- a/web/src/components/molecules/Asset/AssetList/index.tsx
+++ b/web/src/components/molecules/Asset/AssetList/index.tsx
@@ -179,5 +179,5 @@ const Wrapper = styled.div`
`;
const StyledPageHeader = styled(PageHeader)`
- margin: 0 8px;
+ border-bottom: 1px solid #00000008;
`;
diff --git a/web/src/components/molecules/Common/CommentsPanel/index.tsx b/web/src/components/molecules/Common/CommentsPanel/index.tsx
index c747eebc3..e78befcf2 100644
--- a/web/src/components/molecules/Common/CommentsPanel/index.tsx
+++ b/web/src/components/molecules/Common/CommentsPanel/index.tsx
@@ -42,7 +42,7 @@ const CommentsPanel: React.FC = ({
trigger={}>
{collapsed ? (
- onCollapse(false)} />
+ onCollapse(false)} />
) : (
<>
@@ -72,7 +72,8 @@ const CommentsPanel: React.FC = ({
export default CommentsPanel;
const StyledIcon = styled(Icon)`
- padding: 12px 20px;
+ padding-top: 12px;
+ justify-content: center;
`;
const ThreadWrapper = styled.div`
@@ -81,7 +82,8 @@ const ThreadWrapper = styled.div`
`;
const Title = styled.h3`
- font-size: 18px;
+ font-size: 16px;
+ line-height: 1.5;
cursor: pointer;
`;
diff --git a/web/src/components/molecules/Common/Form/GroupItem/index.tsx b/web/src/components/molecules/Common/Form/GroupItem/index.tsx
index ff7463beb..183ce8f8e 100644
--- a/web/src/components/molecules/Common/Form/GroupItem/index.tsx
+++ b/web/src/components/molecules/Common/Form/GroupItem/index.tsx
@@ -61,7 +61,11 @@ type Props = {
disableMoveDown?: boolean;
onGetAsset: (assetId: string) => Promise;
onGroupGet: (id: string) => Promise;
- onCheckItemReference?: (value: string, correspondingFieldId: string) => Promise;
+ onCheckItemReference?: (
+ itemId: string,
+ correspondingFieldId: string,
+ groupId?: string,
+ ) => Promise;
};
const GroupItem: React.FC = ({
diff --git a/web/src/components/molecules/Common/LinkAssetModal/LinkAssetModal.tsx b/web/src/components/molecules/Common/LinkAssetModal/LinkAssetModal.tsx
index c21340cba..774111e9e 100644
--- a/web/src/components/molecules/Common/LinkAssetModal/LinkAssetModal.tsx
+++ b/web/src/components/molecules/Common/LinkAssetModal/LinkAssetModal.tsx
@@ -1,5 +1,5 @@
import styled from "@emotion/styled";
-import { useState, useRef, useCallback, useMemo } from "react";
+import { useRef, useCallback, useMemo } from "react";
import Button from "@reearth-cms/components/atoms/Button";
import Icon from "@reearth-cms/components/atoms/Icon";
@@ -74,7 +74,6 @@ const LinkAssetModal: React.FC = ({
onUploadAndLink,
}) => {
const t = useT();
- const [hoveredAssetId, setHoveredAssetId] = useState();
const resetFlag = useRef(false);
const options: OptionConfig = useMemo(
@@ -127,14 +126,10 @@ const LinkAssetModal: React.FC = ({
width: 48,
minWidth: 48,
render: (_, asset) => {
- const isLink =
- (asset.id === linkedAsset?.id && hoveredAssetId !== asset.id) ||
- (asset.id !== linkedAsset?.id && hoveredAssetId === asset.id);
+ const isLink = asset.id !== linkedAsset?.id;
return (