Files

6.7 KiB

Frontend Instructions

General Rules

  • Never edit files inside wwwroot/ directly. All output files are generated by the Gulp build pipeline.
  • All stylesheet sources must be written in SCSS (.scss), not plain CSS.
  • After adding or changing source files, ensure they are listed in Fuchs/bdlconfig.json so they are picked up by the build.

Source File Locations

Type Source path
SCSS (shared/global) Fuchs/css/intranet/
SCSS (module-specific) Fuchs/js/intranet/modules/<module>/ (co-located with the module JS)
JavaScript (core) Fuchs/js/intranet/
JavaScript (modules) Fuchs/js/intranet/modules/<module>/

Output / Bundle Locations

All bundles are written to Fuchs/web/ by the Gulp pipeline. Do not reference these paths as source.

Bundle Context Description
web/fisb.min.css intranet Bootstrap/login CSS
web/fis.min.css intranet Main intranet CSS
web/fis.inv.min.css intranet:inv Invoices module CSS
web/fis.req.min.css intranet:req Requests module CSS
web/fis.rep.min.css intranet:rep Reports module CSS
web/fis.bam.min.css intranet:bam BAM module CSS
web/fisb.min.js intranet Bootstrap/basic JS
web/fis.min.js intranet Main intranet JS
web/fis.inv.de.js intranet:inv Invoices module JS
web/fis.req.de.js intranet:req Requests module JS
web/fis.rep.de.js intranet:rep Reports module JS
web/fis.bam.de.js intranet:bam BAM module JS

bdlconfig.json Entry Format

Fuchs/bdlconfig.json drives all bundle definitions. Each entry has this shape:

{
  "context": "intranet",
  "outputFileName": "web/<bundle-name>.min.css",
  "inputFiles": [
    "css/intranet/oci_variables.scss",
    "css/intranet/fis_variables.scss",
    "css/intranet/<your-file>.scss"
  ],
  "minify": { "enabled": true }
}

SCSS Variable Prepend Rule

Every CSS bundle must include the two variable files as the first inputFiles entries, in this order:

css/intranet/oci_variables.scss
css/intranet/fis_variables.scss

These define the shared design tokens used across all SCSS files. Omitting them will cause compilation errors.

Module Co-location Pattern

Module-specific SCSS files live alongside their JavaScript counterparts under js/intranet/modules/<module>/. When adding a new module:

  1. Create js/intranet/modules/<module>/<module>.scss for module styles.
  2. Add that path to the appropriate context bundle in bdlconfig.json (after the variable files).
  3. Create js/intranet/modules/<module>/<module>.js for module logic.
  4. Add that path to the corresponding JS bundle in bdlconfig.json.

Build Pipeline

The Gulp 4 pipeline (Fuchs/gulpfile.js) reads bdlconfig.json and copyconfig.json.

Available Tasks

Command Description
gulp min:scss Compile and minify all SCSS bundles
gulp min:js Concatenate and minify all JS bundles
gulp min:html Minify HTML bundles
gulp min Run min:js, min:scss, and min:html in parallel
gulp copy Run file copy tasks from copyconfig.json
gulp all Run min and copy in parallel (full build)
gulp clean Delete all bundle output files
gulp watch Watch source files and rebuild on change

Run from the Fuchs/ directory:

cd Fuchs
npx gulp all

How SCSS Compilation Works

  • All .scss files listed in a bundle's inputFiles are concatenated into a single stream, then compiled with node-sass via gulp-sass.
  • The output is then minified with gulp-cssmin and written to web/<bundle>.min.css.
  • .less files in the same bundle are compiled separately and merged with the SCSS output before minification.

How JS Bundling Works

  • All JS files listed in inputFiles are concatenated with gulp-concat.
  • Files listed in inputFiles_tominify are individually minified with gulp-terser before concatenation.
  • When minify.enabled is true (default), the full bundle is also minified via gulp-terser.

npm Dependencies

Runtime packages available via npm (do not copy these into source manually):

Package Usage
jquery DOM/AJAX
js-cookie Cookie access
fg-loadcss Async CSS loading (loadCSS.js, onloadCSS_array.js)
tinymce Rich text editor

These are copied to web/ or wwwroot/lib/ via copyconfig.json entries and the gulp copy task.

Package Destination (gulp copy) Served at
jquery + js-cookie concatenated into Fuchs/web/tools.js ~/web/tools.js
tinymce wwwroot/lib/tinymce/ ~/lib/tinymce/tinymce.min.js

Layout Asset Wiring (Views/Shared/_Layout.cshtml)

Asset loading follows a strict order and is split by authentication state.

Always loaded (before auth check)

<script src="~/web/tools.js" asp-append-version="true"></script>

tools.js contains jQuery and js-cookie. It must be first so all subsequent scripts can use $ and Cookies.

Auth-conditional bundles

@if (isAuth)
{
    <script src="~/lib/tinymce/tinymce.min.js"></script>
    <link rel="stylesheet" href="~/web/fis.min.css" asp-append-version="true" />
    <script src="~/web/fis.min.js" asp-append-version="true"></script>
}
else
{
    <link rel="stylesheet" href="~/web/fisb.min.css" asp-append-version="true" />
    <script src="~/web/fisb.min.js" asp-append-version="true"></script>
}
  • Authenticated (fis.*): full intranet styles + scripts + TinyMCE rich-text editor.
  • Unauthenticated (fisb.*): login-page-only styles + scripts. TinyMCE is not loaded.
  • TinyMCE is always loaded from ~/lib/tinymce/tinymce.min.js (copied by gulp copy from node_modules/tinymce). Never use ~/Scripts/tinymce/ — that path does not exist.

$ocms.auth injection (always)

A <script> block is always rendered (authenticated or not) that writes the $ocms.auth object with the current user's id, email, and authorization level. This lets client-side code read auth state without additional requests.

Per-page module bundles (@section CustomHeader)

Module bundles (fis.inv, fis.req, fis.rep, fis.bam) are not loaded globally. Each view that needs them renders a @section CustomHeader block:

@section CustomHeader {
    <link rel="stylesheet" href="~/web/fis.inv.min.css" asp-append-version="true" />
    <script src="~/web/fis.inv.de.js" asp-append-version="true"></script>
}

_Layout.cshtml renders @RenderSection("CustomHeader", required: false) inside <head>, so only the relevant module assets are fetched for each page.