Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/on-demand-setup-teams-field-groups.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Setup Teams Field Groups
on:
workflow_dispatch:

jobs:
setup_teams_field_groups:
runs-on: ubuntu-latest
environment: Production
container:
image: ghcr.io/yldio/asap-hub/node-python-sq:7b77d99657ab3718ed548ba366ffbcbb15315fd8
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup
id: setup
uses: ./.github/actions/setup-environment
with:
environment-name: Production
- name: Setup Teams Field Groups
run: |
yarn workspace @asap-hub/contentful setup-teams-field-groups
env:
CONTENTFUL_MANAGEMENT_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }}
CONTENTFUL_SPACE_ID: ${{ steps.setup.outputs.crn-contentful-space-id }}
CONTENTFUL_ENV_ID: Production

notify_failure:
runs-on: ubuntu-latest
needs: [setup_teams_field_groups]
if: ${{ failure() }}
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: ./.github/actions/slack/
with:
message: Setup teams field groups failed
webhook: ${{ secrets.SLACK_WEBHOOK }}
status: failure
27 changes: 27 additions & 0 deletions .github/workflows/reusable-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,33 @@ jobs:
CONTENTFUL_MANAGEMENT_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }}
CONTENTFUL_SPACE_ID: ${{ steps.setup.outputs.gp2-contentful-space-id }}

crn-contentful-field-groups:
needs: [crn-contentful-migrate]
# Run after migrations to set up field groups (editorLayout)
if: ${{ (inputs.environment-name == 'Branch' && inputs.crn-contentful-env != 'Development' && inputs.crn-contentful-env !='Production') || inputs.environment-name != 'Branch' }}
runs-on: ubuntu-latest
environment: ${{ inputs.environment-name }}
container:
image: ghcr.io/yldio/asap-hub/node-python-sq:7b77d99657ab3718ed548ba366ffbcbb15315fd8
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup
id: setup
uses: ./.github/actions/setup-environment
with:
environment-name: ${{ inputs.environment-name }}
- name: Setup Teams Field Groups
run: |
yarn workspace @asap-hub/contentful setup-teams-field-groups
env:
CONTENTFUL_MANAGEMENT_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }}
CONTENTFUL_SPACE_ID: ${{ steps.setup.outputs.crn-contentful-space-id }}
CONTENTFUL_ENV_ID: ${{ inputs.crn-contentful-env }}

ses:
needs: [crn-sls-deploy]
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions packages/contentful/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"migrate-project-data": "ts-node ./scripts/migrate-project-data.ts",
"migrate-preliminary-data-sharing": "ts-node ./scripts/migrate-preliminary-data-sharing.ts",
"migrate-impact-categories": "ts-node ./scripts/migrate-impact-categories.ts",
"setup-teams-field-groups": "ts-node ./scripts/setup-teams-field-groups.ts",
"transform-privacy-policy": "ts-node ./scripts/transform-privacy-policy.ts",
"rollback-privacy-policy": "ts-node ./scripts/rollback-privacy-policy.ts",
"watch:babel": "../../scripts/build-babel.sh watch",
Expand Down
119 changes: 119 additions & 0 deletions packages/contentful/scripts/setup-teams-field-groups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import * as contentful from 'contentful-management';

const spaceId = process.env.CONTENTFUL_SPACE_ID!;
const contentfulManagementAccessToken =
process.env.CONTENTFUL_MANAGEMENT_ACCESS_TOKEN!;
const environmentId = process.env.CONTENTFUL_ENV_ID!;

const CONTENT_TYPE_ID = 'teams';
const RESOURCE_GROUP_ID = 'resourceGroup';
const RESOURCE_GROUP_NAME = 'Resource Section';

const RESOURCE_FIELD_IDS = [
'resourceTitle',
'resourceDescription',
'resourceButtonCopy',
'resourceContactEmail',
'resourceLink',
];

const client = contentful.createClient({
accessToken: contentfulManagementAccessToken,
});

async function setupFieldGroups() {
try {
console.log('🚀 Starting field group setup for teams content type...');
console.log(` Space ID: ${spaceId}`);
console.log(` Environment: ${environmentId}`);

// Get space and environment
const space = await client.getSpace(spaceId);
const environment = await space.getEnvironment(environmentId);

// Get the current editor interface
console.log('\n📖 Fetching current editor interface...');
const editorInterface =
await environment.getEditorInterfaceForContentType(CONTENT_TYPE_ID);

// Get all field IDs from the content type
const contentType = await environment.getContentType(CONTENT_TYPE_ID);
const allFieldIds = contentType.fields.map((field) => field.id);

console.log(` Found ${allFieldIds.length} fields in content type`);

// Create the editor layout with field groups
console.log(`\n✨ Creating field group: "${RESOURCE_GROUP_NAME}"`);

// Get remaining fields (not in resource group)
const remainingFieldIds = allFieldIds.filter(
(fieldId) => !RESOURCE_FIELD_IDS.includes(fieldId),
);

// Build the editor layout with a single top-level tab containing a fieldset
// Structure: One tab with regular fields + a collapsible fieldset for resource fields
const editorLayout: any[] = [
{
groupId: 'content',
name: 'Content',
items: [
// Regular fields first
...remainingFieldIds.map((fieldId) => ({ fieldId })),
// Resource fields as a nested fieldset group
{
groupId: RESOURCE_GROUP_ID,
name: RESOURCE_GROUP_NAME,
items: RESOURCE_FIELD_IDS.map((fieldId) => ({ fieldId })),
},
],
},
];

console.log(
` ${remainingFieldIds.length} regular fields + "${RESOURCE_GROUP_NAME}" fieldset`,
);

// Update the editor interface
editorInterface.editorLayout = editorLayout;

// groupControls defines how each group is rendered
// - Top level: topLevelTab
// - Nested groups: fieldset (collapsible section)
editorInterface.groupControls = [
{
groupId: 'content',
widgetId: 'topLevelTab',
widgetNamespace: 'builtin',
},
{
groupId: RESOURCE_GROUP_ID,
widgetId: 'fieldset',
widgetNamespace: 'builtin',
},
];

console.log('\n💾 Saving editor interface...');
await editorInterface.update();

// Re-publish content type to force UI refresh (workaround for Contentful bug)
console.log('\n🔄 Re-publishing content type to refresh UI...');
const publishedContentType = await contentType.publish();
console.log(` Content type version: ${publishedContentType.sys.version}`);

console.log('\n✅ Field groups successfully configured!');
console.log(
` Resource fields (${RESOURCE_FIELD_IDS.length}) are now in "${RESOURCE_GROUP_NAME}" fieldset`,
);
console.log(
'\n🎉 Done! Check your Contentful web app to see the collapsible fieldset.',
);
} catch (error) {
console.error('\n❌ Error setting up field groups:', error);
if (error instanceof Error) {
console.error(' Message:', error.message);
}
process.exit(1);
}
}

setupFieldGroups();