Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
equinor avatar

Workspace Config

  • 1 installs
  • 4 repo stars
  • Updated July 10, 2026
  • equinor/cc-components

Wires Equinor Fusion workspace modules (grid, garden, Power BI, filter, status bar) and HTTP client config in workspace.tsx and frameworkConfig.ts.

About

Creates and edits workspace configuration for Equinor CC apps, wiring Fusion workspace modules like grid, garden, Power BI, filter, and status bar in workspace.tsx and frameworkConfig.ts. A developer uses it when scaffolding or configuring a CC app's WorkspaceWrapper and framework config.

  • Templates for workspace.tsx and frameworkConfig.ts wiring Fusion workspace modules
  • Covers grid, garden, Power BI, filter, status bar, httpClient, context, and bookmarks

Workspace Config by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #1,914 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Jul 24, 2026 (Skillselion catalog sync)
npx skills add https://github.com/equinor/cc-components --skill workspace-config

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
repo stars4
Last updatedJuly 10, 2026
Repositoryequinor/cc-components

What it does

Wires Equinor Fusion workspace modules (grid, garden, Power BI, filter, status bar) and HTTP client config in workspace.tsx and frameworkConfig.ts.

Files

SKILL.mdMarkdownGitHub ↗

Workspace Configuration

Every CC app follows the same workspace wiring pattern. This skill covers workspace.tsx and frameworkConfig.ts.

Workspace Component Pattern (workspace.tsx)

Every WorkspaceWrapper follows this structure:

import {
  useCCApiAccessCheck,
  useContextId,
  useHttpClient,
  usePBIOptions,
  useWorkspaceBookmarks,
  useCloseSidesheetOnContextChange,
  isAffiliateUser,
} from '@cc-components/shared';
import { useFilterConfig } from '@cc-components/shared/workspace-config';
import Workspace from '@equinor/workspace-fusion';
import { CCApiAccessLoading } from '@cc-components/sharedcomponents';
import { useModuleCurrentContext } from '@equinor/fusion-framework-react-module-context';

// Module imports
import { gridModule } from '@equinor/workspace-fusion/grid-module';
import { gardenModule } from '@equinor/workspace-fusion/garden-module';
import { powerBiModule } from '@equinor/workspace-fusion/power-bi-module';

// Local config imports
import { sidesheetConfig } from './sidesheetConfig';
import { useTableConfig } from './tableConfig';
import { useStatusBarConfig } from './statusBarConfig';
import { useGardenConfig } from './gardenConfig';

const appName = '<api-name>'; // e.g. 'work-orders', 'swcr'

const pbi_context_mapping = {
  Facility: { column: 'Facility', table: 'Dim_Facility' },
  ProjectMaster: { column: 'ProjectMaster GUID', table: 'Dim_ProjectMaster' },
} as const;

export const WorkspaceWrapper = () => {
  const contextId = useContextId();
  useCloseSidesheetOnContextChange();
  const client = useHttpClient();
  const { bookmarkKey, currentBookmark, onBookmarkChange } = useWorkspaceBookmarks();
  const { isLoading } = useCCApiAccessCheck(contextId, client, appName);
  const { currentContext } = useModuleCurrentContext();

  const pbi = usePBIOptions(
    '<app>-analytics',
    pbi_context_mapping[currentContext?.type.id as 'ProjectMaster' | 'Facility']
  );

  const filterConfig = useFilterConfig((req) =>
    client.fetch(`/api/contexts/${contextId}/${appName}/filter-model`, req)
  );
  const tableConfig = useTableConfig(contextId);
  const statusBarConfig = useStatusBarConfig(contextId);
  const gardenConfig = useGardenConfig(contextId);

  if (isLoading) return <CCApiAccessLoading />;

  return (
    <Workspace
      appName={appName}
      key={contextId + bookmarkKey}
      currentBookmark={currentBookmark}
      onBookmarkChange={onBookmarkChange}
      workspaceOptions={{
        getIdentifier: (item: any) => item.<entityId>,
        defaultTab: 'grid',
        information: {
          title: '<AppName> Workspace',
          dataSource: 'ProCoSys / Alpha',
          dataRefreshRate: 'Hourly',
          access: 'Internal',
          isAffiliate: isAffiliateUser(),
        },
      }}
      powerBiOptions={pbi}
      filterOptions={filterConfig}
      gardenOptions={gardenConfig}
      gridOptions={tableConfig}
      statusBarOptions={statusBarConfig}
      sidesheetOptions={sidesheetConfig}
      modules={[gridModule, gardenModule, powerBiModule]}
    />
  );
};

Key conventions

  • appName must match the CC API route segment (e.g. 'work-orders', not 'workorder')
  • All config hooks receive contextId as parameter
  • useFilterConfig takes a fetch callback, not a URL
  • Modules are passed as array: [gridModule, gardenModule, powerBiModule]
  • Always include isAffiliate: isAffiliateUser() in workspace information

Framework Config Pattern (frameworkConfig.ts)

import { enableAgGrid } from '@equinor/fusion-framework-module-ag-grid';
import { ComponentRenderArgs, IAppConfigurator } from '@equinor/fusion-framework-react-app';
import { enableContext } from '@equinor/fusion-framework-react-module-context';
import { enableBookmark } from '@equinor/fusion-framework-react-app/bookmark';
import { enableNavigation } from '@equinor/fusion-framework-module-navigation';
import { enableModelViewer, ModelViewerEnvConfig } from '@cc-components/modelviewer';
import { defaultModules } from '@cc-components/shared';
import { themeQuartz } from '@equinor/workspace-fusion/grid';
import buildQuery from 'odata-query';

export const configure = async (config: IAppConfigurator, c: ComponentRenderArgs) => {
  enableNavigation(config, c.env.basename);
  enableBookmark(config);
  enableContext(config, async (builder) => {
    builder.setContextType(['ProjectMaster', 'Facility']);
    builder.setContextParameterFn(({ search, type }) =>
      buildQuery({ search, filter: { type: { in: type } } })
    );
  });

  const envConfig = c.env.config?.environment as AppEnvConfig & ModelViewerEnvConfig;
  if (!envConfig) throw new Error('Failed to load environment config');

  config.configureHttpClient('cc-app', {
    baseUri: envConfig.uri,
    defaultScopes: envConfig.defaultScopes,
  });

  enableAgGrid(config, (b) => {
    b.setModules(defaultModules);
    b.setTheme(themeQuartz.withParams({}));
  });

  enableModelViewer(config, envConfig);
};

Key conventions

  • HTTP client key is always 'cc-app'
  • Context types are ['ProjectMaster', 'Facility']
  • AG Grid uses defaultModules from @cc-components/shared and themeQuartz
  • Model viewer is enabled from @cc-components/modelviewer

Config Index (index.ts)

export { useTableConfig } from './tableConfig';
export { WorkspaceWrapper } from './workspace';
export { configure } from './frameworkConfig';

Checklist

  • [ ] appName matches CC API route segment
  • [ ] getIdentifier returns correct entity ID field
  • [ ] All 5 config hooks wired: filter, table, garden, status bar, sidesheet
  • [ ] Power BI report name matches backend configuration
  • [ ] Framework config enables: navigation, bookmark, context, AG Grid, model viewer
  • [ ] HTTP client configured as 'cc-app'

Related skills

Frontend Developmentfrontendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.