From e1f5e378cd8caa5f2cd17aa6536548acaae55c87 Mon Sep 17 00:00:00 2001 From: Manu Date: Wed, 25 Nov 2020 15:18:36 +0100 Subject: [PATCH] feat(data): add slug to glossary entries (#195) * feat(data): add slug to glossary entries * feat(hasura): put back webhook * feat: update migration and trim fields * refactor(frontend): minor changes --- .../src/components/forms/Lister/index.js | 11 ++++--- .../src/components/glossary/TermForm.js | 4 +++ .../src/pages/glossary/edit/[[...id]].js | 4 +-- targets/frontend/src/pages/glossary/index.js | 7 +++-- targets/hasura/metadata/tables.yaml | 30 +++++++++++++------ .../1606230745147_new_glossary/down.sql | 1 + .../1606230745147_new_glossary/up.sql | 22 ++++++++++++++ 7 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 targets/hasura/migrations/1606230745147_new_glossary/down.sql create mode 100644 targets/hasura/migrations/1606230745147_new_glossary/up.sql diff --git a/targets/frontend/src/components/forms/Lister/index.js b/targets/frontend/src/components/forms/Lister/index.js index bd5bcc7cd..204b9e943 100644 --- a/targets/frontend/src/components/forms/Lister/index.js +++ b/targets/frontend/src/components/forms/Lister/index.js @@ -19,27 +19,26 @@ const Lister = ({ defaultValue = "[]", disabled, ...props }) => { }; Lister.propTypes = { - defaultValue: PropTypes.string, + defaultValue: PropTypes.arrayOf(PropTypes.string), disabled: PropTypes.bool, }; export { Lister }; -function RootLister({ disabled, value: rawEntries, onChange, name }) { - const entries = JSON.parse(rawEntries); +function RootLister({ disabled, value: entries, onChange, name }) { const inputRef = useRef(null); const onAddEntry = () => { const value = inputRef.current.value; if (value === "") return; if (!entries.includes(value)) { - onChange(JSON.stringify([...entries, value])); + onChange([...entries, value.trim()]); } inputRef.current.value = ""; }; const onDeleteEntry = (deletedEntry) => { const entriesCopy = [...entries]; entriesCopy.splice(entriesCopy.indexOf(deletedEntry), 1); - onChange(JSON.stringify(entriesCopy)); + onChange(entriesCopy); }; const handleKeyDown = (event) => { @@ -89,5 +88,5 @@ RootLister.propTypes = { disabled: PropTypes.bool, name: PropTypes.string, onChange: PropTypes.func.isRequired, - value: PropTypes.string, + value: PropTypes.arrayOf(PropTypes.string), }; diff --git a/targets/frontend/src/components/glossary/TermForm.js b/targets/frontend/src/components/glossary/TermForm.js index e87ef38cb..fe98f31ad 100644 --- a/targets/frontend/src/components/glossary/TermForm.js +++ b/targets/frontend/src/components/glossary/TermForm.js @@ -1,4 +1,5 @@ /** @jsx jsx */ +import slugify from "@socialgouv/cdtn-slugify"; import Link from "next/link"; import { useRouter } from "next/router"; import PropTypes from "prop-types"; @@ -40,10 +41,13 @@ export const TermForm = ({ term = {} }) => { const [duplicateTermError, setDuplicateTermError] = useState(false); async function onSubmit(data) { + data.term = data.term.trim(); + data.definition = data.definition.trim(); const result = await editTerm({ term: { ...(term.id && { id: term.id }), ...data, + slug: slugify(data.term), }, }); if (!result.error) { diff --git a/targets/frontend/src/pages/glossary/edit/[[...id]].js b/targets/frontend/src/pages/glossary/edit/[[...id]].js index bc55efc90..3d02f6fb4 100644 --- a/targets/frontend/src/pages/glossary/edit/[[...id]].js +++ b/targets/frontend/src/pages/glossary/edit/[[...id]].js @@ -16,10 +16,10 @@ const getTermQuery = ` query getTerm($id: uuid!) { term: glossary_by_pk(id: $id) { id - abbreviations + term definition + abbreviations references - term variants } } diff --git a/targets/frontend/src/pages/glossary/index.js b/targets/frontend/src/pages/glossary/index.js index c8d61c3d6..f0604fe1e 100644 --- a/targets/frontend/src/pages/glossary/index.js +++ b/targets/frontend/src/pages/glossary/index.js @@ -14,8 +14,9 @@ import { useQuery } from "urql"; const getGlossaryQuery = ` query getGlossary { glossary(order_by: {term: asc}) { - term id + slug + term } } `; @@ -29,7 +30,9 @@ function getTermsByLetter(glossary = []) { ); return alphabet.map((letter) => ({ letter, - terms: glossary.filter(({ term }) => term[0].toUpperCase() === letter), + terms: glossary.filter( + ({ slug }) => slug.substring(0, 1).toUpperCase() === letter + ), })); } diff --git a/targets/hasura/metadata/tables.yaml b/targets/hasura/metadata/tables.yaml index 5cf128535..c27d7a3fe 100644 --- a/targets/hasura/metadata/tables.yaml +++ b/targets/hasura/metadata/tables.yaml @@ -353,32 +353,41 @@ permission: check: {} columns: - - id - - term - abbreviations + - references - variants - definition - - references + - slug + - term + - created_at + - updated_at + - id backend_only: false select_permissions: - role: public permission: columns: - abbreviations - - definition - references - - term - variants + - definition + - slug + - term + - created_at + - updated_at - id filter: {} - role: user permission: columns: - abbreviations - - definition - references - - term - variants + - definition + - slug + - term + - created_at + - updated_at - id filter: {} update_permissions: @@ -386,10 +395,13 @@ permission: columns: - abbreviations - - definition - references - - term - variants + - definition + - slug + - term + - created_at + - updated_at - id filter: {} check: null diff --git a/targets/hasura/migrations/1606230745147_new_glossary/down.sql b/targets/hasura/migrations/1606230745147_new_glossary/down.sql new file mode 100644 index 000000000..3d38fa8fb --- /dev/null +++ b/targets/hasura/migrations/1606230745147_new_glossary/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."glossary"; diff --git a/targets/hasura/migrations/1606230745147_new_glossary/up.sql b/targets/hasura/migrations/1606230745147_new_glossary/up.sql new file mode 100644 index 000000000..2b1cf5f07 --- /dev/null +++ b/targets/hasura/migrations/1606230745147_new_glossary/up.sql @@ -0,0 +1,22 @@ +DROP TABLE "public"."glossary"; + +CREATE TABLE "public"."glossary"( + "id" uuid NOT NULL DEFAULT gen_random_uuid(), + "term" text NOT NULL, + "slug" text NOT NULL, + "definition" text NOT NULL, + "abbreviations" jsonb NOT NULL DEFAULT jsonb_build_array(), + "variants" jsonb NOT NULL DEFAULT jsonb_build_array(), + "references" jsonb NOT NULL DEFAULT jsonb_build_array(), + "created_at" timestamptz NOT NULL DEFAULT now(), + "updated_at" timestamptz NOT NULL DEFAULT now(), + PRIMARY KEY ("id"), + UNIQUE ("slug") +); + +CREATE TRIGGER "set_public_glossary_updated_at" + BEFORE UPDATE ON "public"."glossary" + FOR EACH ROW + EXECUTE PROCEDURE trigger_set_timestamp(); + +COMMENT ON TRIGGER "set_public_glossary_updated_at" ON "public"."glossary" IS 'trigger to set value of column "updated_at" to current timestamp on row update';