Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code widget inside list widget does not show code until clicked #6812

Closed
ashleykolodziej-moodys opened this issue Jun 16, 2023 · 3 comments · Fixed by #7131
Closed

Code widget inside list widget does not show code until clicked #6812

ashleykolodziej-moodys opened this issue Jun 16, 2023 · 3 comments · Fixed by #7131
Labels
area: extensions/widgets/code pinned type: bug code to address defects in shipped code

Comments

@ashleykolodziej-moodys
Copy link

Describe the bug
When a code widget is used inside of a list widget and the code widget has data, it will not display the code until the code widget is clicked.

I have a screenshare demonstrating what I'm seeing here:

Screen.Recording.2023-06-16.at.1.48.34.PM.mp4

To Reproduce

  • Create a custom editor widget using the list widget type using the code widget in the list widget fields.
  • Add code to the code widget and save.
  • Refresh the page in Decap CMS.
  • Open the list widget.
  • Open the list item you edited.
  • The stored code will not display.
  • Click the code widget.
  • The stored code will display.

Expected behavior
The code should be visible when the list item is opened. It should not required a click to see the code.

Screenshots

Applicable Versions:

  • Netlify CMS version: netlify-cms-app 2.15.72, netlify-cms-core 2.55.2, netlify-cms 2.10.192
  • Git provider: GitHub (this is reproducable running Decap CMS locally)
  • OS: Mac Ventura 13.4
  • Browser version Chrome 114.0.5735.106
  • Node.JS version: v18.12.1

CMS configuration

local_backend: true

backend:
  name: proxy
  proxy_url: http://localhost:8082/api/v1
  branch: main

# These lines should *not* be indented
media_folder: "static/img" # Media files will be stored in the repo under static/images/uploads
public_folder: "/img/" # The src attribute for uploaded media will begin with /images/uploads

collections:
  - name: docs
    label: Docs
    label_singular: "Doc"
    folder: "docs"
    path: "{{title}}/{{id}}"
    slug: "{{id}}"
    create: true
    nested: { depth: 100 } # accepts an optional summary template
    fields:
      - { label: "title", name: "title", widget: "string" }
      - {
          label: "Navigation Position",
          name: "sidebar_position",
          widget: "number",
          required: false,
          hint: "Changes the position of this page in the navigation.",
        }
      - {
          label: "System Status",
          name: "system_status",
          widget: "select",
          required: true,
          multiple: false,
          options: ["Proposed", "In Design", "In Development", "Stable"],
          hint: "The design system component status. Use stable for components in production.",
        }
      - {
          label: "System Sources",
          name: "system_sources",
          widget: "select",
          multiple: true,
          required: false,
          options:
            [
              "Material UI",
              "AG Grid",
            ],
          hint: "Select libraries or data sources this component is dependent on.",
        }
      - {
          label: "Similar Components",
          name: "related_components",
          widget: "select",
          multiple: true,
          required: false,
          options:
            [
              "Autocomplete",
              "Button",
              "ButtonGroup",
              "Checkbox",
              "Chip",
              "Link",
              "RadioGroup",
              "Select",
              "TextField",
              "ToggleButton",
              "ToggleButtonGroup",
              "Tabs",
              "TransferList",
            ],
          hint: "Select the components this component is related to. Previews of each component will show in the order selected here, at the bottom of the page.",
        }
      - { label: "Page Content", name: "body", widget: "markdown" }
    allow_nesting: true
    meta: { path: { widget: string, label: "Path", index_file: "index" } }

Additional context
admin/index.html

Note: this won't work out of the box, as ExampleGrid is a custom component and MUI needs to be loaded, but it should give you an idea of what I'm doing.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style>
      /* Workaround for text editor https://github.com/decaporg/decap-cms/issues/5092 */
      textarea {
        -webkit-user-modify: read-write !important;
      }
    </style>
  </head>
  <body>
    <!-- Include the script that builds the page and powers Netlify CMS -->
    <script
      type="application/javascript"
      src="/design-system/js/netlify-cms.js"
    ></script>
    <script>
      // Example Grid
      CMS.registerEditorComponent({
        // Internal id of the component
        id: "examplegrid",
        // Visible label
        label: "Example Grid",
        // Fields the user need to fill out when adding an instance of the component
        fields: [
          {
            name: "items",
            label: "Examples",
            widget: "list",
            fields: [
              {
                name: "name",
                label: "Name",
                widget: "string",
                hint: "This is used to label the example in the admin area. It does not show on the website.",
              },
              {
                name: "type",
                label: "Type",
                widget: "select",
                options: [
                  {
                    label: "Theme Preview",
                    value: "",
                  },
                  {
                    label: "Do (Success)",
                    value: "success",
                  },
                  {
                    label: "Don't (Error)",
                    value: "error",
                  },
                ],
              },
              {
                name: "code",
                label: "Example Code",
                widget: "code",
                default_language: "jsx",
                output_code_only: true,
                hint: "Add or choose a file with valid React or MUI code. This will render the preview area of the example. Specify imports as needed in your file.",
              },
              {
                name: "description",
                label: "Description",
                widget: "text",
                hint: "Use this area to provide notes and context about this example. Line breaks and code are not supported and will be removed on save.\n &#x26A0; There is a bug in Decap CMS where this field jumps your cursor to the end as you type, so please do any updates to this field in a text editor and paste them in until we're able to find a fix. Follow along with https://github.com/decaporg/decap-cms/issues/5092#issuecomment-1594997948 if you'd like to stay updated.",
              },
            ],
          },
        ],
        pattern:
          /^import\sExampleGrid\sfrom\s"(.*?)";\n\n<ExampleGrid>(.*?)<\/ExampleGrid>$/ms,
        fromBlock: function (match) {
          const itemRegex = /<Box[^>]*>(.*?)<\/Box>/gs;

          const items = match[2].match(itemRegex);

          const parsedDataObj = [];

          items.forEach(function (item) {
            const dataRegex =
              /<Box[^>]*\sname\s*=\s*['"]([^'"]*)['"][^>]*>(\s*?)<DocExample type="(.*?)">\n*([\s\S]*?)\n*<\/DocExample>(\s*?)<Typography.*?>(\s*?)(.*?)(\s*?)<\/Typography>$/ms;

            const match = item.match(dataRegex);

            parsedDataObj.push({
              name: match[1],
              type: match[3],
              code: match[4],
              description: match[7].trim(),
            });
          });

          return {
            items: parsedDataObj,
          };
        },
        toBlock: function (data) {
          return [
            'import ExampleGrid from "@site/src/components/ExampleGrid";',
            `<ExampleGrid>
${data.items
  .map((item) => {
    return `  <Box
    sx={{
      display: "grid",
      gap: 1,
      gridTemplateRows: "subgrid",
      gridRow: "span 2",
    }}
    name="${item.name}"
  >
    <DocExample type="${item.type}">${item.code}</DocExample>
    <Typography variant="body2">
      ${item.description.replace(/(\r\n|\n|\r)/gm, "")}
    </Typography>
  </Box>`;
  })
  .join("\n")}
</ExampleGrid>`,
          ].join("\n\n");
        },
        toPreview: function (data) {
          return `<section>This is the PreviewGrid component. For an accurate view, please save and view in browser.</section>`;
        },
      });
    </script>
  </body>
</html>
@martinjagodic
Copy link
Member

@ashleykolodziej-moodys this is an impressive bug report, thanks!

@martinjagodic
Copy link
Member

@ashleykolodziej-moodys can you check if this bug is still there in Decap 3?

@ashleykolodziej-moodys
Copy link
Author

Hey @martinjagodic! I am still seeing this after upgrading to 3. Here's what I see when I open the widget using my original instructions:

Screenshot 2023-10-05 at 12 35 16 PM

CMS version: decap-cms-app 3.0.7, decap-cms-core 3.2.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: extensions/widgets/code pinned type: bug code to address defects in shipped code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants