From 20ccdda6094aa46c1d88fa51e497aab0a48c05cc Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Wed, 17 Feb 2021 22:38:18 +0100 Subject: [PATCH 1/2] Add a notes field to equipments --- .../main/scala/docspell/common/Ident.scala | 2 +- .../src/main/resources/docspell-openapi.yml | 2 + .../restserver/conv/Conversions.scala | 8 ++-- .../h2/V1.20.1__equipment_description.sql | 2 + .../V1.20.1__equipment_description.sql | 2 + .../V1.20.1__equipment_description.sql | 2 + .../docspell/store/records/REquipment.scala | 11 ++++-- .../src/main/elm/Comp/EquipmentForm.elm | 38 ++++++++++++++++--- .../webapp/src/main/elm/Comp/SearchMenu.elm | 2 +- 9 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 modules/store/src/main/resources/db/migration/h2/V1.20.1__equipment_description.sql create mode 100644 modules/store/src/main/resources/db/migration/mariadb/V1.20.1__equipment_description.sql create mode 100644 modules/store/src/main/resources/db/migration/postgresql/V1.20.1__equipment_description.sql diff --git a/modules/common/src/main/scala/docspell/common/Ident.scala b/modules/common/src/main/scala/docspell/common/Ident.scala index 95e58bc6..ded29dc8 100644 --- a/modules/common/src/main/scala/docspell/common/Ident.scala +++ b/modules/common/src/main/scala/docspell/common/Ident.scala @@ -4,9 +4,9 @@ import java.security.SecureRandom import java.util.UUID import cats.Eq +import cats.Order import cats.effect.Sync import cats.implicits._ -import cats.Order import io.circe.{Decoder, Encoder} import scodec.bits.ByteVector diff --git a/modules/restapi/src/main/resources/docspell-openapi.yml b/modules/restapi/src/main/resources/docspell-openapi.yml index 9ac23cd8..01ecdfb1 100644 --- a/modules/restapi/src/main/resources/docspell-openapi.yml +++ b/modules/restapi/src/main/resources/docspell-openapi.yml @@ -4980,6 +4980,8 @@ components: description: DateTime type: integer format: date-time + notes: + type: string ReferenceList: description: Listing of entities with their id and a name. diff --git a/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala b/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala index ddd36923..00c5957b 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala @@ -617,15 +617,17 @@ trait Conversions { // equipment def mkEquipment(re: REquipment): Equipment = - Equipment(re.eid, re.name, re.created) + Equipment(re.eid, re.name, re.created, re.notes) def newEquipment[F[_]: Sync](e: Equipment, cid: Ident): F[REquipment] = timeId.map({ case (id, now) => - REquipment(id, cid, e.name, now, now) + REquipment(id, cid, e.name, now, now, e.notes) }) def changeEquipment[F[_]: Sync](e: Equipment, cid: Ident): F[REquipment] = - Timestamp.current[F].map(now => REquipment(e.id, cid, e.name, e.created, now)) + Timestamp + .current[F] + .map(now => REquipment(e.id, cid, e.name, e.created, now, e.notes)) // idref diff --git a/modules/store/src/main/resources/db/migration/h2/V1.20.1__equipment_description.sql b/modules/store/src/main/resources/db/migration/h2/V1.20.1__equipment_description.sql new file mode 100644 index 00000000..0c18a644 --- /dev/null +++ b/modules/store/src/main/resources/db/migration/h2/V1.20.1__equipment_description.sql @@ -0,0 +1,2 @@ +ALTER TABLE "equipment" +ADD COLUMN "notes" text; diff --git a/modules/store/src/main/resources/db/migration/mariadb/V1.20.1__equipment_description.sql b/modules/store/src/main/resources/db/migration/mariadb/V1.20.1__equipment_description.sql new file mode 100644 index 00000000..57d43464 --- /dev/null +++ b/modules/store/src/main/resources/db/migration/mariadb/V1.20.1__equipment_description.sql @@ -0,0 +1,2 @@ +ALTER TABLE `equipment` +ADD COLUMN `notes` mediumtext; diff --git a/modules/store/src/main/resources/db/migration/postgresql/V1.20.1__equipment_description.sql b/modules/store/src/main/resources/db/migration/postgresql/V1.20.1__equipment_description.sql new file mode 100644 index 00000000..0c18a644 --- /dev/null +++ b/modules/store/src/main/resources/db/migration/postgresql/V1.20.1__equipment_description.sql @@ -0,0 +1,2 @@ +ALTER TABLE "equipment" +ADD COLUMN "notes" text; diff --git a/modules/store/src/main/scala/docspell/store/records/REquipment.scala b/modules/store/src/main/scala/docspell/store/records/REquipment.scala index d1cfa83a..5befc011 100644 --- a/modules/store/src/main/scala/docspell/store/records/REquipment.scala +++ b/modules/store/src/main/scala/docspell/store/records/REquipment.scala @@ -14,7 +14,8 @@ case class REquipment( cid: Ident, name: String, created: Timestamp, - updated: Timestamp + updated: Timestamp, + notes: Option[String] ) {} object REquipment { @@ -26,7 +27,8 @@ object REquipment { val name = Column[String]("name", this) val created = Column[Timestamp]("created", this) val updated = Column[Timestamp]("updated", this) - val all = NonEmptyList.of[Column[_]](eid, cid, name, created, updated) + val notes = Column[String]("notes", this) + val all = NonEmptyList.of[Column[_]](eid, cid, name, created, updated, notes) } val T = Table(None) @@ -39,7 +41,7 @@ object REquipment { .insert( t, t.all, - fr"${v.eid},${v.cid},${v.name},${v.created},${v.updated}" + fr"${v.eid},${v.cid},${v.name},${v.created},${v.updated},${v.notes}" ) } @@ -54,7 +56,8 @@ object REquipment { DML.set( t.cid.setTo(v.cid), t.name.setTo(v.name), - t.updated.setTo(now) + t.updated.setTo(now), + t.notes.setTo(v.notes) ) ) } yield n diff --git a/modules/webapp/src/main/elm/Comp/EquipmentForm.elm b/modules/webapp/src/main/elm/Comp/EquipmentForm.elm index 28ffe0f4..3e0ab5eb 100644 --- a/modules/webapp/src/main/elm/Comp/EquipmentForm.elm +++ b/modules/webapp/src/main/elm/Comp/EquipmentForm.elm @@ -16,11 +16,13 @@ import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onInput) import Styles as S +import Util.Maybe type alias Model = { equipment : Equipment , name : String + , notes : Maybe String } @@ -28,6 +30,7 @@ emptyModel : Model emptyModel = { equipment = Api.Model.Equipment.empty , name = "" + , notes = Nothing } @@ -38,23 +41,37 @@ isValid model = getEquipment : Model -> Equipment getEquipment model = - Equipment model.equipment.id model.name model.equipment.created + { id = model.equipment.id + , name = model.name + , created = model.equipment.created + , notes = model.notes + } type Msg = SetName String | SetEquipment Equipment + | SetNotes String update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) update _ msg model = case msg of SetEquipment t -> - ( { model | equipment = t, name = t.name }, Cmd.none ) + ( { model + | equipment = t + , name = t.name + , notes = t.notes + } + , Cmd.none + ) SetName n -> ( { model | name = n }, Cmd.none ) + SetNotes str -> + ( { model | notes = Util.Maybe.fromString str }, Cmd.none ) + view : Model -> Html Msg view model = @@ -84,9 +101,7 @@ view model = view2 : Model -> Html Msg view2 model = div [ class "flex flex-col" ] - [ div - [ class "mb-4" - ] + [ div [ class "mb-4" ] [ label [ for "equipname" , class S.inputLabel @@ -109,4 +124,17 @@ view2 model = ] [] ] + , div [ class "mb-4" ] + [ h3 [ class S.header3 ] + [ text "Notes" + ] + , div [ class "" ] + [ textarea + [ onInput SetNotes + , Maybe.withDefault "" model.notes |> value + , class S.textAreaInput + ] + [] + ] + ] ] diff --git a/modules/webapp/src/main/elm/Comp/SearchMenu.elm b/modules/webapp/src/main/elm/Comp/SearchMenu.elm index 140147af..237c08e2 100644 --- a/modules/webapp/src/main/elm/Comp/SearchMenu.elm +++ b/modules/webapp/src/main/elm/Comp/SearchMenu.elm @@ -479,7 +479,7 @@ updateDrop ddm flags settings msg model = SetConcEquip id -> let equip = - Equipment id.id id.name 0 + Equipment id.id id.name 0 Nothing in resetAndSet (ConcEquipmentMsg (Comp.Dropdown.SetSelection [ equip ])) From 5181283b1b3cc4b0cc4fad3d1932a0da097b681b Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Wed, 17 Feb 2021 22:47:49 +0100 Subject: [PATCH 2/2] Add a short-name to organizations --- .../src/main/resources/docspell-openapi.yml | 2 + .../restserver/conv/Conversions.scala | 9 ++-- .../migration/h2/V1.20.2__org_shortname.sql | 2 + .../mariadb/V1.20.2__org_shortname.sql | 2 + .../postgresql/V1.20.2__org_shortname.sql | 2 + .../store/queries/QOrganization.scala | 2 +- .../store/records/ROrganization.scala | 42 ++++++++++------- modules/webapp/src/main/elm/Comp/OrgForm.elm | 45 +++++++++++++++---- 8 files changed, 78 insertions(+), 28 deletions(-) create mode 100644 modules/store/src/main/resources/db/migration/h2/V1.20.2__org_shortname.sql create mode 100644 modules/store/src/main/resources/db/migration/mariadb/V1.20.2__org_shortname.sql create mode 100644 modules/store/src/main/resources/db/migration/postgresql/V1.20.2__org_shortname.sql diff --git a/modules/restapi/src/main/resources/docspell-openapi.yml b/modules/restapi/src/main/resources/docspell-openapi.yml index 01ecdfb1..84ed7417 100644 --- a/modules/restapi/src/main/resources/docspell-openapi.yml +++ b/modules/restapi/src/main/resources/docspell-openapi.yml @@ -5069,6 +5069,8 @@ components: description: DateTime type: integer format: date-time + shortName: + type: string OrganizationList: description: | A list of full organization values. diff --git a/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala b/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala index 00c5957b..90c3e06a 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/conv/Conversions.scala @@ -386,7 +386,8 @@ trait Conversions { Address(ro.street, ro.zip, ro.city, ro.country), v.contacts.map(mkContact).toList, ro.notes, - ro.created + ro.created, + ro.shortName ) } @@ -407,7 +408,8 @@ trait Conversions { v.address.country, v.notes, now, - now + now, + v.shortName ) } yield OOrganization.OrgAndContacts(org, cont) } @@ -431,7 +433,8 @@ trait Conversions { v.address.country, v.notes, v.created, - now + now, + v.shortName ) } yield OOrganization.OrgAndContacts(org, cont) } diff --git a/modules/store/src/main/resources/db/migration/h2/V1.20.2__org_shortname.sql b/modules/store/src/main/resources/db/migration/h2/V1.20.2__org_shortname.sql new file mode 100644 index 00000000..d3ac8559 --- /dev/null +++ b/modules/store/src/main/resources/db/migration/h2/V1.20.2__org_shortname.sql @@ -0,0 +1,2 @@ +ALTER TABLE "organization" +ADD COLUMN "short_name" varchar(254); diff --git a/modules/store/src/main/resources/db/migration/mariadb/V1.20.2__org_shortname.sql b/modules/store/src/main/resources/db/migration/mariadb/V1.20.2__org_shortname.sql new file mode 100644 index 00000000..40cb7611 --- /dev/null +++ b/modules/store/src/main/resources/db/migration/mariadb/V1.20.2__org_shortname.sql @@ -0,0 +1,2 @@ +ALTER TABLE `organization` +ADD COLUMN `short_name` varchar(254); diff --git a/modules/store/src/main/resources/db/migration/postgresql/V1.20.2__org_shortname.sql b/modules/store/src/main/resources/db/migration/postgresql/V1.20.2__org_shortname.sql new file mode 100644 index 00000000..d3ac8559 --- /dev/null +++ b/modules/store/src/main/resources/db/migration/postgresql/V1.20.2__org_shortname.sql @@ -0,0 +1,2 @@ +ALTER TABLE "organization" +ADD COLUMN "short_name" varchar(254); diff --git a/modules/store/src/main/scala/docspell/store/queries/QOrganization.scala b/modules/store/src/main/scala/docspell/store/queries/QOrganization.scala index a966c90a..05415b5b 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QOrganization.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QOrganization.scala @@ -25,7 +25,7 @@ object QOrganization { ): Stream[ConnectionIO, (ROrganization, Vector[RContact])] = { val valFilter = query.map { q => val v = s"%$q%" - c.value.like(v) || org.name.like(v) || org.notes.like(v) + c.value.like(v) || org.name.like(v) || org.shortName.like(v) || org.notes.like(v) } val sql = Select( select(org.all, c.all), diff --git a/modules/store/src/main/scala/docspell/store/records/ROrganization.scala b/modules/store/src/main/scala/docspell/store/records/ROrganization.scala index 0e8efafd..339c07e3 100644 --- a/modules/store/src/main/scala/docspell/store/records/ROrganization.scala +++ b/modules/store/src/main/scala/docspell/store/records/ROrganization.scala @@ -21,7 +21,8 @@ case class ROrganization( country: String, notes: Option[String], created: Timestamp, - updated: Timestamp + updated: Timestamp, + shortName: Option[String] ) {} object ROrganization { @@ -31,16 +32,17 @@ object ROrganization { final case class Table(alias: Option[String]) extends TableDef { val tableName = "organization" - val oid = Column[Ident]("oid", this) - val cid = Column[Ident]("cid", this) - val name = Column[String]("name", this) - val street = Column[String]("street", this) - val zip = Column[String]("zip", this) - val city = Column[String]("city", this) - val country = Column[String]("country", this) - val notes = Column[String]("notes", this) - val created = Column[Timestamp]("created", this) - val updated = Column[Timestamp]("updated", this) + val oid = Column[Ident]("oid", this) + val cid = Column[Ident]("cid", this) + val name = Column[String]("name", this) + val street = Column[String]("street", this) + val zip = Column[String]("zip", this) + val city = Column[String]("city", this) + val country = Column[String]("country", this) + val notes = Column[String]("notes", this) + val created = Column[Timestamp]("created", this) + val updated = Column[Timestamp]("updated", this) + val shortName = Column[String]("short_name", this) val all = NonEmptyList.of[Column[_]]( oid, @@ -52,7 +54,8 @@ object ROrganization { country, notes, created, - updated + updated, + shortName ) } @@ -64,7 +67,7 @@ object ROrganization { DML.insert( T, T.all, - fr"${v.oid},${v.cid},${v.name},${v.street},${v.zip},${v.city},${v.country},${v.notes},${v.created},${v.updated}" + fr"${v.oid},${v.cid},${v.name},${v.street},${v.zip},${v.city},${v.country},${v.notes},${v.created},${v.updated},${v.shortName}" ) def update(v: ROrganization): ConnectionIO[Int] = { @@ -80,7 +83,8 @@ object ROrganization { T.city.setTo(v.city), T.country.setTo(v.country), T.notes.setTo(v.notes), - T.updated.setTo(now) + T.updated.setTo(now), + T.shortName.setTo(v.shortName) ) ) for { @@ -106,7 +110,11 @@ object ROrganization { } def findLike(coll: Ident, orgName: String): ConnectionIO[Vector[IdRef]] = - run(select(T.oid, T.name), from(T), T.cid === coll && T.name.like(orgName)) + run( + select(T.oid, T.name), + from(T), + T.cid === coll && (T.name.like(orgName) || T.shortName.like(orgName)) + ) .query[IdRef] .to[Vector] @@ -141,7 +149,9 @@ object ROrganization { nameQ: Option[String], order: Table => Column[_] ): ConnectionIO[Vector[IdRef]] = { - val nameFilter = nameQ.map(s => T.name.like(s"%${s.toLowerCase}%")) + val nameFilter = nameQ.map(s => + T.name.like(s"%${s.toLowerCase}%") || T.shortName.like(s"%${s.toLowerCase}%") + ) val sql = Select(select(T.oid, T.name), from(T), T.cid === coll &&? nameFilter) .orderBy(order(T)) sql.build.query[IdRef].to[Vector] diff --git a/modules/webapp/src/main/elm/Comp/OrgForm.elm b/modules/webapp/src/main/elm/Comp/OrgForm.elm index 1f3603dc..58522d17 100644 --- a/modules/webapp/src/main/elm/Comp/OrgForm.elm +++ b/modules/webapp/src/main/elm/Comp/OrgForm.elm @@ -20,6 +20,7 @@ import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onInput) import Styles as S +import Util.Maybe type alias Model = @@ -28,6 +29,7 @@ type alias Model = , addressModel : Comp.AddressForm.Model , contactModel : Comp.ContactField.Model , notes : Maybe String + , shortName : Maybe String } @@ -38,6 +40,7 @@ emptyModel = , addressModel = Comp.AddressForm.emptyModel , contactModel = Comp.ContactField.emptyModel , notes = Nothing + , shortName = Nothing } @@ -57,6 +60,7 @@ getOrg model = , address = Comp.AddressForm.getAddress model.addressModel , contacts = Comp.ContactField.getContacts model.contactModel , notes = model.notes + , shortName = model.shortName } @@ -66,6 +70,7 @@ type Msg | AddressMsg Comp.AddressForm.Msg | ContactMsg Comp.ContactField.Msg | SetNotes String + | SetShortName String update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) @@ -79,7 +84,14 @@ update flags msg model = ( m2, c2 ) = update flags (ContactMsg (Comp.ContactField.SetItems t.contacts)) m1 in - ( { m2 | org = t, name = t.name, notes = t.notes }, Cmd.batch [ c1, c2 ] ) + ( { m2 + | org = t + , name = t.name + , notes = t.notes + , shortName = t.shortName + } + , Cmd.batch [ c1, c2 ] + ) AddressMsg am -> let @@ -99,14 +111,12 @@ update flags msg model = ( { model | name = n }, Cmd.none ) SetNotes str -> - ( { model - | notes = - if str == "" then - Nothing + ( { model | notes = Util.Maybe.fromString str } + , Cmd.none + ) - else - Just str - } + SetShortName str -> + ( { model | shortName = Util.Maybe.fromString str } , Cmd.none ) @@ -184,6 +194,25 @@ view2 mobile settings model = ] [] ] + , div + [ class "mb-4" ] + [ label + [ for "org-short-name" + , class S.inputLabel + ] + [ text "Short Name" + ] + , input + [ type_ "text" + , onInput SetShortName + , placeholder "Abbreviation" + , Maybe.withDefault "" model.shortName + |> value + , name "org-short-name" + , class S.textInput + ] + [] + ] , div [ class "mb-4" ] [ h3 [ class S.header3 ] [ text "Address"