Skip to content

Entry is missing or inaccessible #1459

@j-quelly

Description

@j-quelly
Screenshot 2023-08-03 at 12 35 48 PM
import React from 'react';
import { Grid, Box, FormControl } from '@contentful/f36-components';
import { EditorAppSDK, FieldAppSDK } from '@contentful/app-sdk';
import { useSDK } from '@contentful/react-apps-toolkit';
import { Field, FieldWrapper } from '@contentful/default-field-editors';
import { JsonEditor } from '@contentful/field-editor-json';

// Patches the sdk to include the help text
const getHelpText = (fieldId: string, sdk: EditorAppSDK) => {
  return sdk?.editor?.editorInterface?.controls?.find((field) => field.fieldId === fieldId)?.settings?.helpText || '';
}

// Converts a field into <FieldAPI> data type, which is the expected data type for many API methods
const getFieldAPI = (fieldId: string, sdk: EditorAppSDK) => {
  return sdk.entry.fields[fieldId].getForLocale(sdk.locales.default);
}

// Creates a <FieldExtensionSDK> type that can be passed to components from the default-field-editors package
const getFieldExtensionSdk = (fieldId: string, sdk: EditorAppSDK): FieldAppSDK => {
  return {
    ...sdk,
    ids: {
      extension: '',
      app: '',
      environmentAlias: '',
      field: '',
      ...sdk.ids,
    },
    field: getFieldAPI(fieldId, sdk),
    window: {
      updateHeight: (height?: number) => null,
      startAutoResizer: () => null,
      stopAutoResizer: () => null,
    },
    // TODO: missing some invocation property, not sure what this does...
    // @ts-ignore
    parameters: {
      installation: {},
      instance: {
        helpText: getHelpText(fieldId, sdk)
      },
    }
  };
}

// we need to patch the sdk to include the widget id
const getWidgetId = (fieldId: string, sdk: EditorAppSDK) => {
  return sdk?.editor?.editorInterface?.controls?.find((field) => field.fieldId === fieldId)?.widgetId || '';
}

// we need to patch the sdk to include the field name
const getFieldName = (fieldId: string, sdk: EditorAppSDK) => {
  return sdk?.contentType?.fields?.find((field) => field.id === fieldId)?.name || '';
}

// helper function to make generating a field configuration easier
const getFieldProps = ({ fieldId, sdk }: { fieldId: string, sdk: EditorAppSDK }) => {
  return {
    sdk: getFieldExtensionSdk(fieldId, sdk),
    widgetId: getWidgetId(fieldId, sdk),
    name: getFieldName(fieldId, sdk),
  };
}

const TYPES = {
  NONE: undefined,
  DEFAULT: 'Default',
  CARDS_ROW: 'Cards Row',
  LOGO_WALL: 'Logo Wall',
};

const Entry = () => {
  const sdk = useSDK<EditorAppSDK>();
  const triggerElement = getFieldProps({ fieldId: 'type', sdk });
  const [currentType, setCurrentType] = React.useState(triggerElement.sdk.field.getValue());
  React.useEffect(() => {
    triggerElement.sdk.field.onValueChanged((value) => {
      setCurrentType(value);
    });
  });

  const [isFocused, setIsFocused] = React.useState({ styles: false });


  const fields = [
    {
      shouldRenderWhenType: [TYPES.NONE, TYPES.DEFAULT, TYPES.CARDS_ROW, TYPES.LOGO_WALL],
      props: getFieldProps({ fieldId: 'internalTitle', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.NONE, TYPES.DEFAULT, TYPES.CARDS_ROW, TYPES.LOGO_WALL],
      props: getFieldProps({ fieldId: 'type', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.DEFAULT],
      props: getFieldProps({ fieldId: 'defaultLayout', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.DEFAULT],
      props: getFieldProps({ fieldId: 'defaultBody', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.DEFAULT],
      props: getFieldProps({ fieldId: 'defaultMedia', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.CARDS_ROW],
      props: getFieldProps({ fieldId: 'cardsRowheader', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.CARDS_ROW],
      props: getFieldProps({ fieldId: 'components', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.LOGO_WALL],
      props: getFieldProps({ fieldId: 'logos', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.DEFAULT, TYPES.CARDS_ROW, TYPES.LOGO_WALL],
      props: getFieldProps({ fieldId: 'backgroundColor', sdk }),
    },
    {
      shouldRenderWhenType: [TYPES.DEFAULT, TYPES.CARDS_ROW, TYPES.LOGO_WALL],
      props: getFieldProps({ fieldId: 'styles', sdk }),
    },
  ];

  return (
    <Grid
      style={{ maxWidth: '816px', marginLeft: 'auto', marginRight: 'auto' }}
      marginTop="spacingXl"
      columns="1fr"
      rowGap="spacingM"
      columnGap="spacingM"
    >
      <Grid.Item>
        {fields.map((field) => {
          if (field.shouldRenderWhenType.includes(currentType)) {
            switch (field.props.widgetId) {
              case 'objectEditor':
                // NOTE: we're using the json editor because the default json field seems to be throwing an error
                return (
                  <Box 
                    paddingLeft="spacingL" 
                    paddingRight="spacingL" 
                    onFocus={() => {
                      setIsFocused({ ...isFocused, styles: true });
                    }}
                    onBlur={() => {
                      setIsFocused({ ...isFocused, styles: false });
                    }}
                  >
                    <Box 
                      style={{ 
                        borderLeft: isFocused.styles ? '3px solid #0059C8' : '3px solid #CFD9E0' 
                      }} 
                      paddingLeft='spacingM'
                    >
                      <FormControl>
                        <FormControl.Label 
                          style={{ 
                            color: '#67728A', 
                            fontFamily: 'var(--font-stack-primary)', 
                            fontWeight: 'var(--font-weight-normal)' 
                          }}>
                            {field.props.name}
                          </FormControl.Label>
                        <JsonEditor field={field.props.sdk.field} isInitiallyDisabled={false} />
                        <FormControl.HelpText>{field.props.sdk.parameters.instance.helpText}</FormControl.HelpText>
                      </FormControl>
                    </Box>
                  </Box>
                );
              default:
                return (
                  <FieldWrapper sdk={field.props.sdk} name={field.props.name} key={field.props.sdk.field.id}>
                    <Field sdk={field.props.sdk} widgetId={field.props.widgetId} />
                  </FieldWrapper>
                );
            }
          } else {
            return null;
          }
        })}
      </Grid.Item>
    </Grid>
  );
};

export default Entry;
  "dependencies": {
    "@contentful/app-sdk": "^4.22.1",
    "@contentful/default-field-editors": "^1.4.10",
    "@contentful/f36-components": "4.48.0",
    "@contentful/f36-tokens": "4.0.2",
    "@contentful/field-editor-json": "^3.3.1",
    "@contentful/react-apps-toolkit": "1.2.16",
    "contentful-management": "10.39.2",
    "emotion": "10.0.27",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-scripts": "5.0.1"
  },

Maybe it's related to this?
Screenshot 2023-08-03 at 1 21 38 PM

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleUsed to mark when there was no activity for a set period of time

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions