From c5aec8aaf09b91ad1287df6ad924be6df34e1d19 Mon Sep 17 00:00:00 2001 From: Ben Surgison Date: Wed, 12 Apr 2023 17:24:52 +0100 Subject: [PATCH 1/2] Make the manage prototype pages independent of the govuk-frontend plugin --- CHANGELOG.md | 4 +- __tests__/spec/build.js | 5 ++ .../change-service-name.cypress.js | 8 +-- .../edit-home-page.cypress.js | 8 +-- .../remove-govuk-frontend.cypress.js | 53 ++++++++++++++ govuk-prototype-kit.config.json | 1 - .../sass/{internal => }/manage-prototype.scss | 69 +++++++++++++++++++ lib/assets/sass/prototype.scss | 8 +-- lib/build.js | 69 ++++++++++++++++--- lib/manage-prototype-handlers.js | 2 +- .../govuk-prototype-kit/layouts/unbranded.njk | 2 +- lib/nunjucks/views/manage-prototype/index.njk | 8 +-- .../views/manage-prototype/layout.njk | 4 ++ .../plugin-install-or-uninstall.njk | 1 + .../views/manage-prototype/plugins.njk | 2 +- .../views/manage-prototype/stylesheets.njk | 1 + .../views/manage-prototype/templates.njk | 1 + lib/utils/paths.js | 1 - migrator/migration-steps.spec.js | 1 + npm-shrinkwrap.json | 18 ++--- package.json | 4 +- server.js | 20 ++++-- 22 files changed, 240 insertions(+), 50 deletions(-) create mode 100644 cypress/e2e/plugins/2-prototype-kit-plugin-tests/remove-govuk-frontend.cypress.js rename lib/assets/sass/{internal => }/manage-prototype.scss (86%) create mode 100644 lib/nunjucks/views/manage-prototype/stylesheets.njk diff --git a/CHANGELOG.md b/CHANGELOG.md index 298c8f752d..9ab4b98ce7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ - [#2120: View templates with default layout](https://github.com/alphagov/govuk-prototype-kit/pull/2120) Viewing templates in Manage Prototype now works even if app/views/layouts/main.html is missing +- [#2118: Make the manage prototype pages independent of the govuk-frontend plugin](https://github.com/alphagov/govuk-prototype-kit/pull/2118) + - [#2116: Fix migration script for layouts](https://github.com/alphagov/govuk-prototype-kit/pull/2116) - [#2100: Make sure exact versions of plugins are installed from the kit](https://github.com/alphagov/govuk-prototype-kit/pull/2100) @@ -15,7 +17,7 @@ ### New features -- [#2088: Plugin authors can now use scripts with type module](https://github.com/alphagov/govuk-prototype-kit/pull/2049) +- [#2088: Plugin authors can now use scripts with type module](https://github.com/alphagov/govuk-prototype-kit/pull/2088) ### Fixes diff --git a/__tests__/spec/build.js b/__tests__/spec/build.js index b5eaaed71b..803d34fc84 100644 --- a/__tests__/spec/build.js +++ b/__tests__/spec/build.js @@ -35,6 +35,11 @@ describe('the build pipeline', () => { jest.spyOn(fse, 'mkdirSync').mockImplementation(() => {}) jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {}) jest.spyOn(fse, 'writeFileSync').mockImplementation(() => {}) + jest.spyOn(fse, 'readJsonSync').mockImplementation(() => ({ + sass: ['test.scss'], + dependencies: { 'govuk-frontend': '4.0.0' }, + version: '13.0.1' + })) jest.spyOn(sass, 'compile').mockImplementation((css, options) => ({ css })) diff --git a/cypress/e2e/dev/5-management-tests/change-service-name.cypress.js b/cypress/e2e/dev/5-management-tests/change-service-name.cypress.js index 043b671fc0..12b2f2cdbd 100644 --- a/cypress/e2e/dev/5-management-tests/change-service-name.cypress.js +++ b/cypress/e2e/dev/5-management-tests/change-service-name.cypress.js @@ -35,18 +35,18 @@ describe('change service name', () => { cy.task('log', 'Visit the manage prototype page') cy.get(serverNameQuery).contains(originalText) - cy.get('.app-task-list__item') + cy.get('.govuk-prototype-kit-manage-prototype-task-list__item') .contains(appConfigPath) - .get('.app-task-list__tag').contains('To do') + .get('.govuk-prototype-kit-manage-prototype-task-list__tag').contains('To do') cy.task('replaceTextInFile', { filename: appConfig, originalText, newText }) waitForApplication(managePagePath) cy.get(serverNameQuery).contains(newText) - cy.get('.app-task-list__item') + cy.get('.govuk-prototype-kit-manage-prototype-task-list__item') .contains(appConfigPath) - .get('.app-task-list__tag').contains('Done') + .get('.govuk-prototype-kit-manage-prototype-task-list__tag').contains('Done') cy.visit('/index') cy.get('.govuk-heading-xl').contains(newText) diff --git a/cypress/e2e/dev/5-management-tests/edit-home-page.cypress.js b/cypress/e2e/dev/5-management-tests/edit-home-page.cypress.js index 8f6287770f..9ba6fd5bdb 100644 --- a/cypress/e2e/dev/5-management-tests/edit-home-page.cypress.js +++ b/cypress/e2e/dev/5-management-tests/edit-home-page.cypress.js @@ -26,9 +26,9 @@ describe('edit home page', () => { cy.task('log', 'Visit the manage prototype templates page') - cy.get('.app-task-list__item') + cy.get('.govuk-prototype-kit-manage-prototype-task-list__item') .contains(appHomePath) - .get('.app-task-list__tag').contains('To do') + .get('.govuk-prototype-kit-manage-prototype-task-list__tag').contains('To do') cy.visit('/index') cy.get('.govuk-heading-xl').contains(originalText) @@ -37,9 +37,9 @@ describe('edit home page', () => { waitForApplication(managePagePath) - cy.get('.app-task-list__item') + cy.get('.govuk-prototype-kit-manage-prototype-task-list__item') .contains(appHomePath) - .get('.app-task-list__tag').contains('Done') + .get('.govuk-prototype-kit-manage-prototype-task-list__tag').contains('Done') cy.visit('/index') cy.get('.govuk-heading-xl').contains(newText) diff --git a/cypress/e2e/plugins/2-prototype-kit-plugin-tests/remove-govuk-frontend.cypress.js b/cypress/e2e/plugins/2-prototype-kit-plugin-tests/remove-govuk-frontend.cypress.js new file mode 100644 index 0000000000..d76b62f060 --- /dev/null +++ b/cypress/e2e/plugins/2-prototype-kit-plugin-tests/remove-govuk-frontend.cypress.js @@ -0,0 +1,53 @@ +const { managePluginsPagePath, performPluginAction } = require('../plugin-utils') +const { uninstallPlugin, installPlugin } = require('../../utils') + +const plugin = 'govuk-frontend' +const pluginName = 'GOV.UK Frontend' +const dependentPlugin = '@govuk-prototype-kit/common-templates' + +describe('Manage prototype pages without govuk-frontend', () => { + it('Uninstall govuk-frontend', () => { + uninstallPlugin(dependentPlugin) + + cy.task('waitUntilAppRestarts') + cy.visit(`${managePluginsPagePath}/uninstall?package=${plugin}`) + + cy.get('#plugin-action-button').contains('Uninstall').click() + + performPluginAction('uninstall', plugin, pluginName) + + cy.task('log', 'Make sure govuk-frontend is uninstalled') + cy.get(`[data-plugin-package-name="${plugin}"]`) + .find('button') + .contains('Install') + + cy.task('log', 'Test home page') + cy.get('a').contains('Home').click() + cy.get('h1').contains('Manage your prototype') + + cy.task('log', 'Test templates page') + cy.get('a').contains('Templates').click() + cy.get('h1').contains('Templates') + + cy.task('log', 'Test plugins page') + cy.get('a').contains('Plugins').click() + cy.get('h1').contains('Plugins') + + cy.task('log', `Install the ${plugin} plugin`) + + cy.get(`[data-plugin-package-name="${plugin}"]`) + .scrollIntoView() + .find('button') + .contains('Install') + .click() + + performPluginAction('install', plugin, pluginName) + + cy.task('log', 'Make sure govuk-frontend is installed') + cy.get(`[data-plugin-package-name="${plugin}"]`) + .find('button') + .contains('Uninstall') + + installPlugin(dependentPlugin) + }) +}) diff --git a/govuk-prototype-kit.config.json b/govuk-prototype-kit.config.json index e9984abbab..e70d634377 100644 --- a/govuk-prototype-kit.config.json +++ b/govuk-prototype-kit.config.json @@ -6,7 +6,6 @@ ], "nunjucksPaths": "/lib/nunjucks", "nunjucksFilters": "/lib/filters/core-filters", - "sass": "/lib/assets/sass/internal/manage-prototype.scss", "scripts": [ "/lib/assets/javascripts/kit.js", "/lib/assets/javascripts/auto-store-data.js" diff --git a/lib/assets/sass/internal/manage-prototype.scss b/lib/assets/sass/manage-prototype.scss similarity index 86% rename from lib/assets/sass/internal/manage-prototype.scss rename to lib/assets/sass/manage-prototype.scss index a2d69f27c2..cf0a93bd86 100644 --- a/lib/assets/sass/internal/manage-prototype.scss +++ b/lib/assets/sass/manage-prototype.scss @@ -1,3 +1,72 @@ + +// Import GOV.UK Frontend within the kit dependency +@import ".tmp/sass/kit-frontend-dependency"; + +.govuk-prototype-kit-manage-prototype-task-list { + list-style-type: none; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + @include govuk-media-query($from: tablet) { + min-width: 550px; + } +} + +.govuk-prototype-kit-manage-prototype-task-list__section { + display: table; + @include govuk-font($size:24, $weight: bold); +} + +.govuk-prototype-kit-manage-prototype-task-list__section-number { + display: table-cell; + + @include govuk-media-query($from: tablet) { + min-width: govuk-spacing(6); + padding-right: 0; + } +} + +.govuk-prototype-kit-manage-prototype-task-list__items { + @include govuk-font($size: 19); + @include govuk-responsive-margin(9, "bottom"); + list-style: none; + padding-left: 0; + @include govuk-media-query($from: tablet) { + padding-left: govuk-spacing(6); + } +} + +.govuk-prototype-kit-manage-prototype-task-list__item { + border-bottom: 1px solid $govuk-border-colour; + margin-bottom: 0 !important; + padding-top: govuk-spacing(2); + padding-bottom: govuk-spacing(2); + @include govuk-clearfix; +} + +.govuk-prototype-kit-manage-prototype-task-list__item:first-child { + border-top: 1px solid $govuk-border-colour; +} + +.govuk-prototype-kit-manage-prototype-task-list__task-name { + display: block; + @include govuk-media-query($from: 450px) { + float: left; + } +} + +.govuk-prototype-kit-manage-prototype-task-list__tag, +.govuk-prototype-kit-manage-prototype-task-list__task-completed { + margin-top: govuk-spacing(2); + margin-bottom: govuk-spacing(1); + + @include govuk-media-query($from: 450px) { + float: right; + margin-top: 0; + margin-bottom: 0; + } +} + .govuk-prototype-kit-manage-prototype-navigation { border-bottom: 1px solid #1d70b8; } diff --git a/lib/assets/sass/prototype.scss b/lib/assets/sass/prototype.scss index c75f2e9e50..21c55f5083 100644 --- a/lib/assets/sass/prototype.scss +++ b/lib/assets/sass/prototype.scss @@ -4,12 +4,8 @@ // Import GOV.UK Frontend and any plugin styles if plugins have been configured @import ".tmp/sass/plugins"; -// Patterns that aren't in Frontend -@import "patterns/contents-list"; -@import "patterns/mainstream-guide"; -@import "patterns/pagination"; -@import "patterns/related-items"; -@import "patterns/task-list"; +// Patterns that support pages built with legacy templates +@import ".tmp/sass/legacy-patterns"; // SASS that is user defined @import ".tmp/sass/user/application"; diff --git a/lib/build.js b/lib/build.js index 0869600cf5..c1953b4979 100644 --- a/lib/build.js +++ b/lib/build.js @@ -12,17 +12,15 @@ const sass = require('sass') const plugins = require('./plugins/plugins') const { projectDir, - appSassDir, - libSassDir, - tmpDir, tmpSassDir, publicCssDir, shadowNunjucksDir, backupNunjucksDir, - appViewsDir + appViewsDir, + packageDir } = require('./utils/paths') const { recursiveDirectoryContentsSync } = require('./utils') const { startPerformanceTimer, endPerformanceTimer } = require('./utils/performance') @@ -43,6 +41,8 @@ function generateAssetsSync ({ verbose } = {}) { const timer = startPerformanceTimer() plugins.setPluginsByType() clean() + sassKitFrontendDependency() + sassLegacyPatterns() sassPlugins() autoImportComponentsSync() createBackupNunjucksSync() @@ -76,21 +76,74 @@ function ensureTempDirExists (dir = tmpDir) { fse.writeFileSync(path.join(tmpDir, '.gitignore'), '*') } +function getInternalGovUkFrontendDir () { + let internalGovUkFrontendDir = path.join(packageDir, 'node_modules', 'govuk-frontend') + if (!fse.pathExistsSync(internalGovUkFrontendDir)) { + internalGovUkFrontendDir = path.join(projectDir, 'node_modules', 'govuk-frontend') + } + return internalGovUkFrontendDir +} + +function sassInclude (filePath) { + return `@import "${filePath.split(path.sep).join('/')}";` +} + +function sassKitFrontendDependency () { + const timer = startPerformanceTimer() + const internalGovUkFrontendDir = getInternalGovUkFrontendDir() + const internalGovUkFrontendConfig = fse.readJsonSync(path.join(internalGovUkFrontendDir, 'govuk-prototype-kit.config.json')) + const fileContents = internalGovUkFrontendConfig.sass + .map(sassPath => path.join(internalGovUkFrontendDir, sassPath)) + .map(sassInclude) + .join('\n') + ensureTempDirExists(tmpSassDir) + fse.writeFileSync(path.join(tmpSassDir, '_kit-frontend-dependency.scss'), fileContents) + endPerformanceTimer('sassKitFrontendDependency', timer) +} + +function sassLegacyPatterns () { + const timer = startPerformanceTimer() + const packageConfig = fse.readJsonSync(path.join(projectDir, 'package.json')) + let fileContents + if (packageConfig.dependencies['govuk-frontend']) { + fileContents = [ + 'contents-list', + 'mainstream-guide', + 'pagination', + 'related-items', + 'task-list' + ].map(filePath => path.join(libSassDir, 'patterns', filePath)) + .map(sassInclude) + .join('\n') + } else { + fileContents = ` +/* Legacy patterns not included as govuk-frontend plugin not installed */ + ` + } + fse.writeFileSync(path.join(tmpSassDir, '_legacy-patterns.scss'), fileContents) + endPerformanceTimer('sassLegacyPatterns', timer) +} + function sassPlugins () { const timer = startPerformanceTimer() + const packageConfig = fse.readJsonSync(path.join(packageDir, 'package.json')) + const [majorVersion] = packageConfig.version.split('.') let fileContents = '' // Keep $govuk-extensions-url-context for backwards compatibility // TODO: remove in v14 fileContents += '$govuk-extensions-url-context: "/plugin-assets";\n' fileContents += '$govuk-plugins-url-context: "/plugin-assets";\n' - fileContents += '$govuk-prototype-kit-major-version: 13;\n' + fileContents += `$govuk-prototype-kit-major-version: ${majorVersion};\n` + const internalGovUkFrontendDir = getInternalGovUkFrontendDir() + const internalGovUkFrontendConfig = fse.readJsonSync(path.join(internalGovUkFrontendDir, 'govuk-prototype-kit.config.json')) if (plugins.legacyGovukFrontendFixesNeeded()) { + const internalGovUkFrontendAssets = internalGovUkFrontendConfig.assets.map(viewPath => path.join(internalGovUkFrontendDir, viewPath)) fileContents += '$govuk-global-styles: true !default;\n' fileContents += '$govuk-new-link-styles: true !default;\n' - fileContents += '$govuk-assets-path: $govuk-plugin-url-context + "/govuk-frontend/govuk/assets/" !default;\n' + fileContents += `$govuk-assets-path: "${internalGovUkFrontendAssets[0]}" !default;\n` } fileContents += plugins.getFileSystemPaths('sass') - .map(filePath => `@import "${filePath.split(path.sep).join('/')}";`) + .map(sassInclude) .join('\n') ensureTempDirExists(tmpSassDir) fse.writeFileSync(path.join(tmpSassDir, '_plugins.scss'), fileContents) @@ -103,7 +156,7 @@ function proxyUserSassIfItExists (filename) { const proxyFilePath = path.join(tmpSassDir, 'user', filename) const proxyFileLines = [] if (fse.existsSync(userFilePath)) { - proxyFileLines.push(`@import "${userFilePath.split(path.sep).join('/')}";`) + proxyFileLines.push(sassInclude(userFilePath)) } ensureTempDirExists(path.dirname(proxyFilePath)) diff --git a/lib/manage-prototype-handlers.js b/lib/manage-prototype-handlers.js index c5bc75a0bb..89e26bb3c6 100644 --- a/lib/manage-prototype-handlers.js +++ b/lib/manage-prototype-handlers.js @@ -406,7 +406,7 @@ async function getPluginDetails () { const pluginPkgPath = path.join(projectDir, 'node_modules', pack.packageName, 'package.json') const pluginPkg = await fse.pathExists(pluginPkgPath) ? await fse.readJson(pluginPkgPath) : {} pack.installedVersion = pluginPkg.version - if (!['govuk-prototype-kit', 'govuk-frontend'].includes(pack.packageName)) { + if (!['govuk-prototype-kit'].includes(pack.packageName)) { pack.uninstallLink = `${contextPath}/plugins/uninstall?package=${encodeURIComponent(pack.packageName)}` } } diff --git a/lib/nunjucks/govuk-prototype-kit/layouts/unbranded.njk b/lib/nunjucks/govuk-prototype-kit/layouts/unbranded.njk index a759fc767d..05d89c8f1e 100644 --- a/lib/nunjucks/govuk-prototype-kit/layouts/unbranded.njk +++ b/lib/nunjucks/govuk-prototype-kit/layouts/unbranded.njk @@ -1,4 +1,4 @@ -{% extends "govuk-prototype-kit/layouts/govuk-branded.njk" %} +{% extends "govuk/template.njk" %} {% block headIcons %} diff --git a/lib/nunjucks/views/manage-prototype/index.njk b/lib/nunjucks/views/manage-prototype/index.njk index e7bc5cb9cb..a090dac9cb 100644 --- a/lib/nunjucks/views/manage-prototype/index.njk +++ b/lib/nunjucks/views/manage-prototype/index.njk @@ -28,13 +28,13 @@

Start a new prototype

-