Giter Site home page Giter Site logo

fikaproductions / fika-gatsby-source-cockpit Goto Github PK

View Code? Open in Web Editor NEW
23.0 8.0 24.0 674 KB

This is a Gatsby version 2.\*.\* source plugin that feeds the GraphQL tree with Cockpit Headless CMS collections and singletons data. Actually, it supports querying raw texts (and any trivial field types), Markdown, images, galleries, assets, sets, repeaters, layout(-grid)s (currently only without nested images/assets), objects, linked collections and internationalization.

License: GNU General Public License v3.0

JavaScript 100.00%

fika-gatsby-source-cockpit's Introduction

@fika/gatsby-source-cockpit

This is a Gatsby version 2.*.* source plugin that feeds the GraphQL tree with Cockpit Headless CMS collections and singletons data.

Actually, it supports querying raw texts (and any trivial field types), Markdown, images, galleries, assets, sets, repeaters, layout(-grid)s (currently only without nested images/assets), objects, linked collections and internationalization.

Installation

npm install --save @fika/gatsby-source-cockpit

This project has gatsby-source-filesystem, gatsby and react as peer dependencies, don't forget to install them as well.

npm install --save gatsby-source-filesystem gatsby react

Contributing

  1. Fork main project on github here.
  2. Clone your fork.
  3. Create a new branch on your local fork.
  4. Commit and push your changes on this branch.
  5. Create a pull request on the main project by going here, click on "compare across forks" and select your own branch in the "head fork" section.
  6. Compare changes and submit pull request.

Tips and tricks

While developing a GatsbyJS source plugin, it is useful to have a GatsbyJS project on the side in order to test it. To use the local plugin in your project instead of the one on NPM, you can run:

// In the plugin's folder
npm link

// In the GatsbyJS project's folder
npm link @fika/gatsby-source-cockpit

You'll have to install the plugin's peer dependencies in the plugin's folder as well (without saving them):

npm install --no-save gatsby react

Then, in order to unlink the local plugin and use the one from NPM again:

npm uninstall --no-save @fika/gatsby-source-cockpit
npm install

How to use

Add this to your project gatsby-config.js file:

plugins: [
  {
    resolve: 'gatsby-source-filesystem',
    options: {
      name: 'src',
      path: `${__dirname}/src/`,
    },
  },
  {
    resolve: '@fika/gatsby-source-cockpit',
    options: {
      token: 'YOUR_COCKPIT_API_TOKEN',
      baseUrl:
        'YOUR_COCKPIT_API_BASE_URL', // (1)
      locales: ['EVERY_LANGUAGE_KEYS_DEFINED_IN_YOUR_COCKPIT_CONFIGURATION'], // (2)
      collections: [], // (3)
      singletons: [], // (4)
      aliases: {
        collection: {
          A_COLLECTION_NAME: 'AN_ALIAS',
          …
        },
        singleton: {
          A_SINGLETON_NAME: 'AN_ALIAS',
          …
        }
      }, // (5)
      brokenImageReplacement: 'AN_URL_TO_AN_IMAGE', // (6)
    },
  },
]

Notes:

  1. E.g. 'http://localhost:8080'.
  2. E.g. ['en', 'fr'].
  3. The specific Cockpit collections you want to fetch. If empty or null all collections will be fetched. E.g. ['Products', 'Menu']
  4. Same as the collections parameter, but for the Cockpit singletons.
  5. You can specify aliases for any Cockpit collection or singleton. Since it's not possible to have two GraphQL types with the same name in a schema, you can use this configuration to alias for instance a collection and a singleton sharing the same name (or with a difference of capitalization in the first character).
    E.g. (for a singleton and a collection both named 'Team') { collection: { Team: 'Teams' } }.
  6. Replacement for broken image links. If null, the detected broken images will be removed. If an URL to an image, the broken image will be replaced with this image.

Adding the gatsby-source-filesystem dependency to your project grants access to the publicURL field resolver attribute on the file nodes that this plugin generates by extending the GraphQL type of the file nodes. So, as you can guess, the path specified in the plugin options could be anything, we do not need it to load any local files, we are just taking advantage of its extension of the file node type.

How to query

Collections and singletons are converted into nodes. You can access many collection entries at once with this syntax:

(The collection is named 'team' or 'Team' in Cockpit.)

{
  allCockpitTeam(filter: { spiritAnimal: { eq: "tiger" } }) { // (1)
    edges {
      node { // (2)
        cockpitId // (3)
        cockpitCreated // (3)
        cockpitModified // (3)
        cockpitBy // (3)
        cockpitModifiedBy // (3)
        TeamMember1
        TeamMember2
        TeamMember3
        childrenCockpitTeam { ... } // (4)
      }
    }
  }
}

Notes:

  1. You can filter amongst them.
  2. Each node is a collection entry in an array.
  3. You can get the original Cockpit element's id (aka the _id), creation and modification dates and authors' (ids for now) that way.
  4. You can access descendant collection entries within that field if you have hierarchically structured your collection entries in Cockpit (Custom sortable entries turned on).

Or you can access one entry at the time or a singleton that way:

(The collection is named 'definition' or 'Definition' in Cockpit.)

query($locale: String) { // (1)
    cockpitDefinition(cockpitId: { eq: "5bc78a3679ef0740297b4u04" }, lang: { eq: $locale }) { // (2)
        header {
            type
            value
        }
    }
}

Notes:

  1. Using query with a name or not is optional in GraphQL. However, if you want to use variables from your page context, it is mandatory.
  2. You can get the appropriate language by filtering on the lang attribute.

(The singleton is named 'vegetable' or 'Vegetable' in Cockpit.)

{
  cockpitVegetable(lang: { eq: "en" }) {
    category {
      type
      value
    }
  }
}

Special types of Cockpit fields

Texts

Text fields with the option { "slug": true } can access the slug that way:

{
  allCockpitBlogPost {
    edges {
      node {
        title {
          slug
        }
      }
    }
  }
}

Collection-Links

Collection-Link fields will see their value attribute refering to another or many others collection(s) node(s) (GraphQL foreign key). One to many Collection-Links are only supported for multiple entries of a single collection. This an example with a TeamMember collection entry linked within a Team collection:

{
  allCockpitTeam {
    edges {
      node {
        Header {
          type
          value
        }
        TeamMember {
          type // (1)
          value { // (2)
            id
            Name {
              value
            }
            Task {
              value
            }
          }
        }
      }
    }
  }
}

Notes:

  1. The type is 'collectionlink' and it was originally refering to an entry of the TeamMember collection.
  2. The refered node is attached here. The language is preserved across these bindings.

Images and galleries

Image and gallery fields nested within a collection or singleton will be downloaded and will get one or more file(s) node(s) attached under the value attribute like this:

(You can then access the child(ren) node(s) a plugin like gatsby-transformer-sharp would create.)

{
  allCockpitTeamMember {
    edges {
      node {
        Portrait {
          value {
            publicURL // (1)
            childImageSharp {
              fluid {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  }
}

Notes:

  1. You can use this field to access your images if their formats are not supported by gatsby-transformer-sharp which is the case for svg and gif files.

Assets

Just like image fields, asset fields nested within a collection or singleton will be downloaded and will get a file node attached under the value attribute.

You can access the file regardless of its type (document, video, etc.) using the publicURL field resolver attribute on the file node.

Markdowns

Markdown fields nested within a collection or singleton will get a custom Markdown node attached under the value attribute. It mimics a file node — even if there is no existing Markdown file — in order to allow plugins like gatsby-transformer-remark to process them. Moreover, images and assets embedded into the Markdown are downloaded and their paths are updated accordingly. Example:

(You can then access the child node a plugin like gatsby-transformer-remark would create.)

{
  allCockpitDefinition {
    edges {
      node {
        Text {
          value {
            childMarkdownRemark {
              html
            }
            internal {
              content // (1)
            }
          }
        }
      }
    }
  }
}

Notes:

  1. You can access the raw Markdown with this attribute.

Sets

The set field type allows to logically group a number of other fields together.

You can then access their values as an object in the value of the set field.

{
  allCockpitTeamMember {
    edges {
      node {
        ContactData { // field of type set
          value {
            telephone {
              value
            }
            fax {
              value
            }
            email {
              value
            }
          }
        }
      }
    }
  }
}

Repeaters

Repeater fields are one of the most powerful fields in Cockpit and allow support for two distinct use cases:

  1. Repeat any other field type (including the set type) an arbitrary number of times resulting in an array of fields with the same type (E.g. [Image, Image, Image])
  2. Choose from a number of specified fields an arbitrary number of times resulting in an array where each entry might be of a different type (E.g. [Image, Text, Set])

For the first case the values can be queried almost like a normal scalar field. The only difference is that two nested values are needed with the first one representing the array and the second one the value in the array.

{
  allCockpitTeamMember {
    edges {
      node {
        responsibilities { // field of type repeater
          value { // value of repeater (array)
            value // value of repeated field
          }
        }
      }
    }
  }

The second case is a bit more complicated - in order to not cause any GraphQL Schema conflicts each array value must be of the same type. To achieve this the gatsby-source-cockpit plugin implicitly wraps the values in a set field, generating one field in the set for each fields option supplied in the repeater configuration.

E.g. assuming the repeater field is configured with these options:

{
  "fields": [
    {
      "name": "title",
      "type": "text",
      "label": "Some text",
    },
    {
      "name": "photo",
      "type": "image",
      "label": "Funny Photo",
    }
  ]
}

then the following query is necessary to get the data:

{
  allCockpitTeamMember {
    edges {
      node {
        responsibilities { // field of type repeater
          value { // value of repeater (array)
            title {
              value
            }
            photo {
              value {
                ...
              }
            }
          }
        }
      }
    }
  }

Note: For this to work the fields specified in the field option need to have a name attribute which is not required by Cockpit itself. If the name attribute is not set, the plugin will print a warning to the console and generate a name value out of the value of the label attribute but it is recommended to explicitly specify the name value.

Layouts and layout-grids

The layout(-grid) field type allows to compose a view with UI components (buttons, divider, text, custom components, …).

You can access the whole components hierarchy using the parsed field. The type of each component is set in the component field. All the component settings defined in Cockpit are present in the settings field. Some of them are raw, others are processed:

  • class is changed for className;
  • style is processed into a CSS-in-JS-like object;
  • html is accessible unchanged into html, but also accessible processed into html_sanitize (which is sanitized) and into html_react (which is a JS representation of a React component).

E.g.

{
  allCockpitPageLayout {
    edges {
      node {
        layout {
          value {
            parsed
          }
        }
      }
    }
  }
}

Note: Images and assets used in a layout aren't currently supported.

Objects

The object field type allows to structure data as a JSON object. You can get the whole object using the data field.

E.g.

{
  allCockpitLogEntries {
    edges {
      node {
        logEntry {
          value {
            data
          }
        }
      }
    }
  }
}

Powered by   —   

fika-gatsby-source-cockpit's People

Contributors

aequi42 avatar alexlau811 avatar dependabot[bot] avatar digitalgoldfish avatar examinator avatar whippetsaintdogs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fika-gatsby-source-cockpit's Issues

"Cockpit" type prefix no longer unique with support for singletons, ...

With the implementation of support for additional Cockpit entity types we might see the situation where the current typePrefix "Cockpit" might not be unique enough as e.g. there might be a collection with the name Contact and a singleton with the same name leading two two different GraphQL Types with the same name and an inevitable schema conflict.

Solution 1: Use different type prefixes (e.g. CockpitCollection, CockpitSingleton, ...); easy to implement but would be a breaking change.
Solution 2: Detect name clashes in the plugin (also not hard to implement) and automatically rename the problematic entity. It would be possible to also specify an alias mapping in the config in case yomeone isn't happy with the automatic renaming.

Votes? Alternative suggestions?

Load & create nodes for Cockpit Users

Nodes for users should be created in the GraphQL tree and they should be linked to the items/singletons as author/modifier (fields _by and _mby),

404 error if you have a singleton with no fields

Hi,
I have been pulling my hair trying to find what's wrong with this plugin/ my config of Cockpit. I was getting this error.
image

I have found the cause of the issue. I had a singleton with no fields, removing that singleton fixed it.
Maybe someone could implement some sort of checking to prevent this from happening to someone else.

Thanks

wysiwyg inserted photo does not show up

wysiwyg contains an image ( inserted into the editor ) and I cannot retrieve it by using


        Description{
          value
        }

Description is wysiwyg type. However, I am able to easily retrieve the text and sizes.

Tags

For some reason, if you set the type as TAGS, you cannot retrieve Value in graphql.

any workaround this ?

error Plugin @fika/gatsby-source-cockpit returned an error

I have 2 types of error first is generated with

baseUrl:: "http://domain.com/cockpit",

and is

 error Plugin @fika/gatsby-source-cockpit returned an error


  Error: Token config parameter is invalid

  - CockpitService.js:45 CockpitService.validateToken
    [gatsby-cockpit]/[@fika]/gatsby-source-cockpit/src/CockpitService.js:45:13

second one I change the URL and I add a / at the end

baseUrl:: "http://domain.com/cockpit/",

and it turns into

error Plugin @fika/gatsby-source-cockpit returned an error


  TypeError: names.filter is not a function

  - CockpitService.js:91 CockpitService.getCollections
    [gatsby-cockpit]/[@fika]/gatsby-source-cockpit/src/CockpitService.js:91:10


please guide me.

Add support for the Set field type

The set field type is a bit tricky since it can contain all other field types, even another set and a repeater. It's fields need therefore be parsed recursively.

Singletons

Are there any plans to support Singletons?

Creating one as a collection works for now but it would be useful to support this feature.

How to get the person who last modified an entry

My query

query{
  allCockpitHello(limit:2 skip:2) {
    edges {
      node{
cockpitId 
        cockpitCreated
        cockpitModified
        cockpitBy 
        cockpitModifiedBy
      }
    }
  }
  } 

returns

 "cockpitId": "5c90b32864343100000001ab",
            "cockpitCreated": "2019-03-19T09:15:20.000Z",
            "cockpitModified": "2019-03-19T09:15:20.000Z",
            "cockpitBy": "5c6592433565630a8a0002d1",
            "cockpitModifiedBy": "5c6592433565630a8a0002d1"

Admin has created this entry and I wonder how I can query the user which made the last modification because I only get IDs # .

Wrong GraphQL Type for optional fields

Hi,

I'm new to cockpit and I've encountered a strange behaviour regarding "optional fields".
Currently i have a model in Cockpit, which involves Fields that might be empty. The API then responds with an empty string, regardles of the field type (In my case the fields are of the type set, the fields object in the response contains the correct definitions, but the actual items contain an empty string).

{
  "fields": {
    "Name": {
      "name": "Name",
      "type": "text",
      "localize": false,
      "options": []
    },
    "Doors": {
      "name": "Doors",
      "type": "set",
      "localize": false,
      "options": {
        "fields": [
          {
            "name": "Date",
            "type": "date"
          },
          {
            "name": "Time",
            "type": "time"
          }
        ]
      }
    } 
  },
  "entries": [
    {
      "Name": "With Value",
      "Doors": {
        "Date": "2018-05-27",
        "Time": "18:30"
      }
    },
    {
      "Name": "Without Value",
      "Doors": ""
    }
  ]
}

These strange empty Strings confuse the schema-generation of gatsby and result in an GqlType String for Doors, which in turn isn't queryable correctly.
The empty strings are returned for all kind of fields. In my model I also have the types image, markdown and repeater that behave the same way.

I'm wondering, if theres a way to tell Cockpit to return null instead of empty strings or to tell the plugin to ignore those empty strings.

Cheers
Flo

--- edit ---
Looking through the sources of the plugin i came across the createCollectionItem method, which checks if the provided field is an array with values or null before transforming it.

if (
      !(
        Array.isArray(collectionEntry[collectionFieldName]) &&
        collectionEntry[collectionFieldName].length === 0
      ) &&
      collectionEntry[collectionFieldName] != null
    )

This leads me to the conclusion that there might a way to tell cockpit to return more appropiate values for "empty" fields.

If there's no way to configure the return value in cockpit I'd be happy to create a PR which extends this condition to include a check for empty strings (or provide a extension point to inject some middleware into this transformation)

No value attribute for image and gallery field type

Hello.
I'm trying to get image and use gatsby-transformer-sharp plugin like in your example from the plugin docs:

{
  allCockpitTeamMember {
    edges {
      node {
        Portrait {
          value {
            publicURL // (1)
            childImageSharp {
              fluid {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  }
}

But in my GraphiQL i don't see the value attribute for image field type and can't use childImageSharp. I only have type attribute. The same problem is in gallery field type.

The value attribute is available in file filed type but I can't use childImageSharp too.

This is screenshot from my GraphiQL:
image

And this is my gatsby-config.json code:

module.exports = {
  siteMetadata: {
    title: `Example gatsby app`,
    langs: ['pl', 'en'],
    defaultLangKey: 'pl'
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: 'gatsby-plugin-i18n',
      options: {
        langKeyForNull: "any",
        langKeyDefault: 'pl',
        useLangKeyLayout: false,
        prefixDefault: false,
        pagesPaths: ['/src/pages/pl', '/src/pages/en']
      }
    },
    {
      resolve: `gatsby-source-graphql`,
      options: {
        typeName: `Cockpit`,
        fieldName: `cmsAPI`,
        url: `***my-api-url***`
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `src`,
        path: `${__dirname}/src`,
      },
    },
    {
      resolve: '@fika/gatsby-source-cockpit',
      options: {
        token: '***my-token***',
        baseUrl: 'http://***my-domain***.pl/cockpit',
        locales: ['pl', 'en']
      },
    },
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `Example gatsby app`,
        short_name: `App`,
        description: ``,
        lang: `pl`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/assets/images/icon_black.svg`,
      },
    },
    `gatsby-plugin-offline`
  ],
}

What is the proposed use of the cockpit "layout" features?

Preface: I'm brand spanking new to cockpit, and have only been playing around with it for a few hours. My use-case on the front end is Gatsby V2.

When looking at the graphql queries for layout field types, this gets a bit tricky. Because we don't really know what the data structure will be, since the content pieces are all dynamically entered and could be different for each collection entry.

Curious if there's currently a way to handle this that I don't see in the readme. I imagine something with inline fragments in graphql?

Support for populate

When using a collection link field we can't access all the values of the linked entry because the populate query parameter is missing on the requests. There is any simple way to populate nested collections?

Do we need the value attribute at all?

Currently every field in the graphql schema has the properties type and value. However when using the data in gatsby the type isn't needed anymore and we could therefore just assign the value directly to the field name.

I believe the reason for the value is that we need the type to be present for postprocessing of the data (linking images, assets, ...) and then we pass the collection item directly to the createNode function. In my opinion the better approach would be to generate the node from scratch (in CollectionNodeFactory) by copying the values from the cockpit data to a new object getting rid of the superfluous type and value fields in the process.

To not break old gatsby-sites and keep backwards compatibility we might need an option to turn this behaviour off & on.

Sort Order for Custom Sorted Entries

In Cockpit, you can set the option on a collection for "Custom Sorted Entries", then the user can order collection entries by moving them around.

This doesn't seem to change the order of the entries fetched by the allCockpitXXX query, and I don't see any way to determine what the sort order is from the available sort fields.

Is there a way to either retrieve correctly sorted results, or at least get access to some kind of order attribute?

Undefined returned when trying to access gallery

Gallery {
            value {
                publicURL
                childImageSharp {
                    fluid {
                      ...GatsbyImageSharpFluid
                    }
                  }

I am not able to log anything out of GatsbyImageSharpFluid

as it return undefined

is there any example in which I can follow to access my images in gallery ?

fluid

"Invalid asset url" when cockpit is installed in subfolder

Hello,

I've cockpit installed in a subfolder (/cockpit), but all images from galleries are replaced with the "broken image replacement".
The baseUrl in the config is set to http://localhost/cockpit

When it scans all the assets, it adds 2 times /cockpit/cockpit/ which causes the problem I think.

warn Invalid asset url: http://localhost/cockpit/cockpit/storage/uploads/2020/06/04/5ed900d7ee6aapicture.jpg
info Using broken image replacement for missing image

my inline image of markdown from cockpit cms is not transformed by gatsby-remark-image or by gatsby-remark-images-anywhere

my config :

module.exports = {
siteMetadata: {
title: muhzulzidan,
author: muhzulzidan,
description: A student,
siteUrl: https://muhzulzidan.com/,
social: {
twitter: muhzulzidan,
},
},
plugins: [
gatsby-plugin-react-helmet,
{
resolve: gatsby-source-filesystem,
options: {
name: images,
path: ${__dirname}/src/images,
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'src',
path: ${__dirname}/src/,
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'src',
path: ${__dirname}/public/static/,
},
},
my blog-post template :
import React from 'react'
import { graphql } from 'gatsby'
import Helmet from 'react-helmet'
import get from 'lodash/get'
// import Img from 'gatsby-image'
import Layout from '../components/layout'

class BlogPostTemplate extends React.Component {
render() {
const post = get(this.props, 'data.cockpitMarkdown.childMarkdownRemark')

const siteTitle = get(this.props, 'data.site.siteMetadata.title')

return (
  <Layout location={this.props.location}>
    <div style={{ background: '#fff' }}>
      <Helmet title={`${post.frontmatter.title} | ${siteTitle}`} />
      <div >
        {/* <Img
         
          alt={post.title.value}
          fluid={post.image.value.childImageSharp.fluid}
        /> */}
      </div>
      <div >
        <h1 >{post.frontmatter.title}</h1>
        <p
          style={{
            display: 'block',
          }}
        >
          {post.frontmatter.date}
        </p>
        <div
          dangerouslySetInnerHTML={{
            __html: post.html,
          }}
        />
      </div>
    </div>
  </Layout>
)

}
}

export default BlogPostTemplate

export const pageQuery = graphql`
query MyQuery ($slug: String!){
site {
siteMetadata {
title
}
}
cockpitMarkdown(childMarkdownRemark: {frontmatter: {slug: {eq:$slug }}}) {
childMarkdownRemark {
html
frontmatter {
slug
title
tags
date (formatString: "MMMM DD, YYYY")
}
}
}

}

`

and i get
Screenshot from 2020-03-19 17-10-56

Warning caused by repeater field values

Hi, I'm getting a warning caused by my repeater-field and can't query any value. Is the repeater-field already supported in your plugin?

Warning:

warning There are conflicting field types in your data. GraphQL schema will omit those fields.
CockpitPages.content.value[].value:

  • type: object
    value: { imageField: [Object] }
  • type: string
    value: 'Some second content blablaa.'

Edit:
Options JSON of Repeater:

{
  "fields": [
    {
      "type": "textarea",
      "name": "textField",
      "label": "Text"
    },
    {
      "type": "set",
      "name": "addGalleryField",
      "label": "Add Gallery",
      "options": {
        "fields": [
          {
            "type": "text",
            "name": "galleryTitleField",
            "label": "Gallery Title"
          },
          {
            "type": "gallery",
            "name": "galleryField",
            "label": "New Gallery"
          }
        ]
      }
    },
    {
      "type": "set",
      "name": "addImageField",
      "label": "Add Image",
      "options": {
        "fields": [
          {
            "type": "text",
            "name": "imageTitleField",
            "label": "Image Title"
          },
          {
            "type": "image",
            "name": "imageField",
            "label": "New Image"
          }
        ]
      }
    }
  ]
}

Thanks

Argument filter has invalid value

The code in read me file

{
  allCockpitHello(filter: { Name: { eq: "Venus" } }) { 
    edges {
      node { 
        cockpitId 
        cockpitCreated 
        cockpitModified 
        cockpitBy 

      }
    }
  }
}

Which I modified to my needs fails to run giving me

{
  "errors": [
    {
      "message": "Field \"eq\" is not defined by type cockpitHelloConnectionNameInputObject_2.",
      "locations": [
        {
          "line": 2,
          "column": 37
        }
      ]
    }
  ]
}

Error when using `collectionLink` component

When i'm using a collection-link in a singleton, the following error occurs.
Am I doing something wrong or is this a bug?

What kind of information can I provide for you, that could help?

Kind regards

 ERROR 

UNHANDLED REJECTION Encountered an error trying to infer a GraphQL type for: `value___NODE`. There is no corresponding node with the `id` field matching: "Cockpit__Pages__5db30b0065653600230000d0".



  Error: Invariant Violation: Encountered an error trying to infer a GraphQL type for: `value___NODE`. There is no corresponding no  de with the `id` field matching: "Cockpit__Pages__5db30b0065653600230000d0".
  
  - invariant.js:40 invariant
    [gatsby]/[invariant]/invariant.js:40:15
  
  - add-inferred-fields.js:257 getFieldConfigFromFieldNameConvention
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:257:3
  
  - add-inferred-fields.js:161 getFieldConfig
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:161:19
  
  - add-inferred-fields.js:87 Object.keys.forEach.key
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:87:25
  
  - Array.forEach
  
  - add-inferred-fields.js:74 addInferredFieldsImpl
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:74:28
  
  - add-inferred-fields.js:390 getSimpleFieldConfig
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:390:19
  
  - add-inferred-fields.js:168 getFieldConfig
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:168:19
  
  - add-inferred-fields.js:87 Object.keys.forEach.key
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:87:25
  
  - Array.forEach
  
  - add-inferred-fields.js:74 addInferredFieldsImpl
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:74:28
  
  - add-inferred-fields.js:38 addInferredFields
    [gatsby]/[gatsby]/dist/schema/infer/add-inferred-fields.js:38:3
  
  - index.js:98 addInferredType
    [gatsby]/[gatsby]/dist/schema/infer/index.js:98:3
  
  - index.js:64 typesToInfer.map.typeComposer
    [gatsby]/[gatsby]/dist/schema/infer/index.js:64:43
  
  - Array.map
  
  - index.js:64 addInferredTypes
    [gatsby]/[gatsby]/dist/schema/infer/index.js:64:23
  
  - schema.js:140 
    [gatsby]/[gatsby]/dist/schema/schema.js:140:11
  
  - Generator.next

Optional fields not in GraphQL if they don't contain a value in at least one collection item

This problem can be reproduced for any field type however it is most visible with fields that contain objects. (images, assets, repeater, ...).

Assume you have a field of type "image" in your collection schema. This field will be valid and queryable in the GraphQL query as long as at least 1 collection item has an image in this field. If the image is removed (field is emptied) from all collection items the field will no longer be queryable in GraphQL as Gatsby cannot infer it's presence from the loaded items and the previously working build will break.

For singletons (if this is ever implemented in the plugin) it will break quicker as there is only one instance and "optional" image fields are basically impossible to implement/query.

For simple field types like text, html, boolean this only happens if the field is added to a collection but no collection item ever edited & saved. Once one collection item is saved this fields will contain at least the empty string "" and the field will be in the graphql query. (so there is an easy workaround)

Default values for "empty"/"unset fields

This issue is inspired by #6 - I know this issue is closed but I saw it today and I have some comments to add so here we go ...

This problem is something I also deal with from time to time and it is somewhat related but not indentical to #13. And I believe there is a way to implement this functionality without modifying Cockpit but it will require some work on the plugin side.

The outline of the solution:

  • Cockpit allows to specify arbitrary values in the field "options" using the GUI, so you can create a new attribute "gatsbyDefault" containing the value you want to have if the field is unset (undefined, null, "").
  • In the source plugin we can then use this value to fill out the schema returned.

Another solution would be to allow specifying a "plugin" to the gatsby-source-cockpit plugin that gets called with the data retrieved from cockpit and allow modification/extension.

I would eventually be interested to explore this in more depth as the current solution (ignore empty strings) has some problems as well (Fields with only empty strings disappear) but this isn't too high on my priority list.

Missing "Meta" on Image-Gallery

Hi,

I'm using a meta field on images inside an gallery:

{
    "fields": {
        "Name": {
            "name": "Name",
            "type": "text",
            "localize": false,
            "options": []
        },
        "Images": {
            "name": "Images",
            "type": "gallery",
            "localize": false,
            "options": {
                "meta": {
                    "title": {
                        "type": "markdown",
                        "label": "Title"
                    }
                }
            }
        }
    },
    "entries": [
        {
            "Name": "Live",
            "Images": [
                {
                    "meta": {
                        "title": "Vielen Dank an [Max Mustermann](https://foo-bar.com/) für dieses Bild",
                        "asset": "5c27d2256466375024000148"
                    },
                    "path": "/storage/uploads/2018/12/29/5c27d22528c3bsvarta-faran-24.jpg"
                },
                {
                    "meta": {
                        "title": "Vielen Dank an [Max Mustermann](https://foo-bar.com/) für dieses Bild",
                        "asset": "5c27d2246466375024000141"
                    },
                    "path": "/storage/uploads/2018/12/29/5c27d224935c9svarta-faran-21.jpg"
                }
            ],
            "_mby": "5c1fa17d6466377043000010",
            "_by": "5c1fa17d6466377043000010",
            "_modified": 1549904496,
            "_created": 1546113589,
            "_id": "5c27d23564663751760002c4"
        }
    ],
    "total": 1
}

The model is defined as follows:

grafik

However, in my Query I get the following error:

error GraphQL Error Unknown field `meta` on type `image_2`

  file: D:/[path-to-file]/index.js


  20 |           fields {
  21 |             slug
  22 |           }
  23 |           Image {
> 24 |             meta {
     |             ^
  25 |               title
  26 |             }
  27 |             value {
  28 |               childImageSharp {

Are you aware of this issue? I'm not complaining about the missing support for markdown inside the meta-element, but about the complete absence of it.

If this is a new issue, I'd be happy to help out, but need a little pointer into the right direction where to begin :)

TypeError: Cannot destructure property `absolutePath` of 'undefined' or 'null'

Trying to configure this plugin with the latest Cockpit.
Configure @fika/gatsby-source-cockpit, and install the related plugins.
Run gatsby develop and get this error:
error Plugin @fika/gatsby-source-cockpit returned an error

TypeError: Cannot destructure property absolutePath of 'undefined' or 'null'.

  • gatsby-node.js:63 copyFileToStaticFolder
    [cockpitgapp]/[@fika]/gatsby-source-cockpit/gatsby-node.js:63:32

  • gatsby-node.js:37 Object.exports.sourceNodes
    [cockpitgapp]/[@fika]/gatsby-source-cockpit/gatsby-node.js:37:31

error UNHANDLED REJECTION

TypeError: Cannot read property 'filter' of undefined

  • api-runner-node.js:287 Promise.mapSeries.catch.then.results
    [cockpitgapp]/[gatsby]/dist/utils/api-runner-node.js:287:42

  • util.js:16 tryCatcher
    [cockpitgapp]/[bluebird]/js/release/util.js:16:23

  • promise.js:512 Promise._settlePromiseFromHandler
    [cockpitgapp]/[bluebird]/js/release/promise.js:512:31

  • promise.js:569 Promise._settlePromise
    [cockpitgapp]/[bluebird]/js/release/promise.js:569:18

  • promise.js:614 Promise._settlePromise0
    [cockpitgapp]/[bluebird]/js/release/promise.js:614:10

  • promise.js:694 Promise._settlePromises
    [cockpitgapp]/[bluebird]/js/release/promise.js:694:18

  • async.js:138 _drainQueueStep
    [cockpitgapp]/[bluebird]/js/release/async.js:138:12

  • async.js:131 _drainQueue
    [cockpitgapp]/[bluebird]/js/release/async.js:131:9

  • async.js:147 Async._drainQueues
    [cockpitgapp]/[bluebird]/js/release/async.js:147:5

  • async.js:17 Immediate.Async.drainQueues
    [cockpitgapp]/[bluebird]/js/release/async.js:17:14
    Environment
    System:
    OS: macOS 10.14
    CPU: x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    Shell: 2.7.1 - /usr/local/bin/fish
    Binaries:
    Node: 10.9.0 - /usr/local/bin/node
    npm: 6.4.1 - /usr/local/bin/npm
    Browsers:
    Chrome: 70.0.3538.77
    Firefox: 63.0
    Safari: 12.0
    npmPackages:
    gatsby: ^2.0.37 => 2.0.37
    gatsby-image: ^2.0.19 => 2.0.19
    gatsby-plugin-favicon: ^3.1.4 => 3.1.4
    gatsby-plugin-manifest: ^2.0.7 => 2.0.7
    gatsby-plugin-offline: ^2.0.11 => 2.0.11
    gatsby-plugin-react-helmet: ^3.0.1 => 3.0.1
    gatsby-plugin-sharp: ^2.0.11 => 2.0.11
    gatsby-plugin-styled-components: ^3.0.1 => 3.0.1
    gatsby-plugin-typography: ^2.2.1 => 2.2.1
    @fika/gatsby-source-cockpit: ^1.0.4 => 1.0.4
    gatsby-source-filesystem: ^2.0.7 => 2.0.7
    gatsby-transformer-sharp: ^2.1.7 => 2.1.7
    npmGlobalPackages:
    gatsby-cli: 2.4.4

Add support for the Object field type

The object field type allows to specify a JSON object of arbitrary shape. This field needs to be implemented similar to the Layout field type as that the whole JSON Object needs to be stored as is without any field type inference from Gatsby(see extend-field-type.js) for how it is done for Layout.

Contrary to the Layout no further processing is required.

allCockpit* returns each node twice

When I run any allCockpit query, each node is returned twice.

Example query:

{
  allCockpitProjects {
    edges {
      node {
        cockpitId
      }
    }
  }
}

Returns the following:

{
  "data": {
    "allCockpitProjects": {
      "edges": [
        {
          "node": {
            "cockpitId": "5c548b9b3162395098000393"
          }
        },
        {
          "node": {
            "cockpitId": "5c548a9f3162394dfe000341"
          }
        },
        {
          "node": {
            "cockpitId": "5c548a173162394c22000221"
          }
        },
        {
          "node": {
            "cockpitId": "5c548adb3162394eb7000387"
          }
        },
        {
          "node": {
            "cockpitId": "5c548b9b3162395098000393"
          }
        },
        {
          "node": {
            "cockpitId": "5c548a9f3162394dfe000341"
          }
        },
        {
          "node": {
            "cockpitId": "5c548a173162394c22000221"
          }
        },
        {
          "node": {
            "cockpitId": "5c548adb3162394eb7000387"
          }
        }
      ]
    }
  }
}

I have 4 entries in the Collection, the first 4 cockpitIds are unique, but the last 4 are repeats.

Error: BaseUrl config parameter is invalid or there is no internet connection

Hi guys,
I am really new to Web development, recently I came across with Gatsby and wanted to use cockpit as the CMS for the backend.

After some googling, I found this plugin.
I was a little bit confuse with folder structure however I read the tutorial on Medium, so I have the gatsby folder and cockpit folder separated.

I have start the PHP server with

php -S localhost:8080

And I logged into admin page everything works pretty well.

for the gatsby-config.js

{
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'src',
        path: `${__dirname}/src/`,
      },
    },
    {
      resolve: '@fika/gatsby-source-cockpit',
      options: {
        token: 'b9723f07b8d190db7cb6996837d48b',
        baseUrl:'http://localhost:8080', // (1)
        locales: ['en'], // (2)
        collections: ['pages', 'projects'], // (3)
        singletons: [], // (4)
        aliases: {
          collection: {
            pages:"pages",
            projects:"projects"
          },
          singleton: {
           
          }
        }, // (5)
      },
    },

but I got an error when i do gatsby develop

"@fika/gatsby-source-cockpit" threw an error while running the sourceNodes lifecycle:

BaseUrl config parameter is invalid or there is no internet connection



  Error: BaseUrl config parameter is invalid or there is no internet connection
  
  - CockpitService.js:44 CockpitService.validateBaseUrl
    [website]/[@fika]/gatsby-source-cockpit/src/CockpitService.js:44:13
  

warn The @fika/gatsby-source-cockpit plugin has generated no Gatsby nodes. Do you need it?

I hope to find out what's the problem and solution, it is quite an important project for me, hopefully I would get some love from you guys! Thank you very much!

Support for hierarchical collections

Cockpit allows to arrange collection entries in a hierarchical structure

image

The current implementation of the source plugin however will only create nodes for the root items. I've implemented support for reading the full hierarchical structure in my fork. If this feature is of interest I can prepare a pull request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.