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

Add support for @contentful/app-sdk #575

Closed
ashsingh1790 opened this issue Jan 29, 2021 · 7 comments
Closed

Add support for @contentful/app-sdk #575

ashsingh1790 opened this issue Jan 29, 2021 · 7 comments

Comments

@ashsingh1790
Copy link

I am working on creating an entry editor for some content model. I am using @contentful/app-sdk and @contentful/forma-36-react-components. I am able to have the UI the way I want with the forma-36 components but I also want to use @contentful/field-editor-reference to have access to the original functionality of the field.

The problem I am running into is when I pass sdk to the MultipleEntryReferenceEditor component from @contentful/field-editor-reference. I get the following error

Type ‘import("/node_modules/@contentful/app-sdk/dist/types").FieldExtensionSDK’ is not assignable to type ‘import("/node_modules/contentful-ui-extensions-sdk/dist/types").FieldExtensionSDK’.

I believe Contentful recommends using @contentful/app-sdk over contentful-ui-extensions-sdk but @contentful/field-editor-reference has a transient dependency on contentful-ui-extensions-sdk.

@caroillemann
Copy link

I experience the same issue but found a way to get around it. So until it's properly fixed, you can maybe try that.

In stead of using the sdk directly, I convert it to the type any.

import { MultipleEntryReferenceEditor } from '@contentful/field-editor-reference';

// ...

const Field = (props: FieldProps) => {
  // If you only want to extend Contentful's default editing experience
  // reuse Contentful's editor components
  // -> https://www.contentful.com/developers/docs/extensibility/field-editors/
  const { sdk } = props
  const sdkCast: any = sdk as any;
  return (
    <MultipleEntryReferenceEditor
      isInitiallyDisabled={false}
      hasCardEditActions={true}
      sdk={sdkCast}
      viewType='link'
      parameters={{
        instance: {
          showCreateEntityAction: true,
          showLinkEntityAction: true,
        },
      }}
    ></MultipleEntryReferenceEditor>
  );
};

@ashsingh1790
Copy link
Author

ashsingh1790 commented Jan 29, 2021

Thanks @caroillemann. Now it is showing some errors in index.tsx. The app works fine without the MultipleReferenceEditor component.

src/index.tsx

import React from 'react';
import { render } from 'react-dom';

import {
  AppExtensionSDK,
  FieldExtensionSDK,
  SidebarExtensionSDK,
  DialogExtensionSDK,
  EditorExtensionSDK,
  PageExtensionSDK,
  BaseExtensionSDK,
  init,
  locations
} from '@contentful/app-sdk';
import '@contentful/forma-36-react-components/dist/styles.css';
import '@contentful/forma-36-fcss/dist/styles.css';
import '@contentful/forma-36-tokens/dist/css/index.css';
import './index.css';

import Config from './components/ConfigScreen';
import EntryEditor from './components/EntryEditor';
import Page from './components/Page';
import Sidebar from './components/Sidebar';
import Field from './components/Field';
import Dialog from './components/Dialog';

import LocalhostWarning from './components/LocalhostWarning';

if (process.env.NODE_ENV === 'development' && window.self === window.top) {
  // You can remove this if block before deploying your app
  const root = document.getElementById('root');
  render(<LocalhostWarning />, root);
} else {
  init((sdk: BaseExtensionSDK) => {
    const root = document.getElementById('root');

    // All possible locations for your app
    // Feel free to remove unused locations
    // Dont forget to delete the file too :)
    const ComponentLocationSettings = [
      {
        location: locations.LOCATION_APP_CONFIG,
        component: <Config sdk={(sdk as unknown) as AppExtensionSDK} />
      },
      {
        location: locations.LOCATION_ENTRY_FIELD,
        component: <Field sdk={(sdk as unknown) as FieldExtensionSDK} />
      },
      {
        location: locations.LOCATION_ENTRY_EDITOR,
        component: <EntryEditor sdk={(sdk as unknown) as EditorExtensionSDK} />
      },
      {
        location: locations.LOCATION_DIALOG,
        component: <Dialog sdk={(sdk as unknown) as DialogExtensionSDK} />
      },
      {
        location: locations.LOCATION_ENTRY_SIDEBAR,
        component: <Sidebar sdk={(sdk as unknown) as SidebarExtensionSDK} />
      },
      {
        location: locations.LOCATION_PAGE,
        component: <Page sdk={(sdk as unknown) as PageExtensionSDK} />
      }
    ];

    // Select a component depending on a location in which the app is rendered.
    ComponentLocationSettings.forEach(componentLocationSetting => {
      if (sdk.location.is(componentLocationSetting.location)) {
        render(componentLocationSetting.component, root);
      }
    });
  });
}

src/components/EntryEditor.tsx

import React from 'react';
import { Accordion, AccordionItem, TextField } from '@contentful/forma-36-react-components';
import { EditorExtensionSDK, FieldExtensionSDK } from '@contentful/app-sdk';
import { MultipleEntryReferenceEditor } from '@contentful/field-editor-reference';
interface EditorProps {
  sdk: EditorExtensionSDK;
}

interface MyReferenceEditorProps {
  sdk: FieldExtensionSDK
}

const LinkedField = (props: MyReferenceEditorProps) => {
  const { sdk } = props
  const sdkCast: any = sdk as any;
  return (
    <MultipleEntryReferenceEditor
      isInitiallyDisabled={false}
      hasCardEditActions={true}
      sdk={sdkCast}
      viewType='link'
      parameters={{
        instance: {
          showCreateEntityAction: true,
          showLinkEntityAction: true,
        },
      }}
    ></MultipleEntryReferenceEditor>
  );
};

const Entry = (props: EditorProps) => {
  const { sdk } = props
  const { entry } = sdk;
  const { fields } = entry;
  return <>
    <div>
      <TextField
        name="abc"
        id="123"
        labelText="User Name"
        countCharacters
        value={fields.description.getValue()}
        width="full"
      />
    </div>
    <div>
      <Accordion>
        <AccordionItem title="What payment methods do you accept?">
          Customers on the Team tier can pay with a credit card (American Express,
          MasterCard or Visa). Enterprise customers have the choice of paying with a
          credit card or wire transfer.
          </AccordionItem>
      </Accordion>
    </div>
    <LinkedField sdk={sdk as any} />
  </>;
};

export default Entry;

error
contentful-app-sdk

This is the example I am trying to implement with @contentful/app-sdk and @contentful/forma-36-react-components

@suevalov
Copy link
Contributor

All field editors were updated to use app-sdk. Please update to the latest version.

@tonyneel923
Copy link

@suevalov if I run yarn add @contentful/field-editor-reference@latest and then pass sdk from entry editor to MultipleEntryReferenceEditor I get the same error as above.

What is the way to fix this?

@tonyneel923
Copy link

tonyneel923 commented Jul 8, 2021

In case anyone comes across this bug as well you can hack a solution together from entry editor sdk like so

const sdkCast: FieldExtensionSDK  = {
    ...sdk,
    field: sdk.entry.fields["fieldName"].getForLocale('en-US')
  } as FieldExtensionSDK

@sami616
Copy link

sami616 commented Jan 26, 2024

Hi @tonyneel923, do you know if there is an official solution for getting access to the fieldsdk from then entrysdk ? Or do we still need this workaround?

@hayder86al
Copy link

Why is this closed? Is it solved yet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants