Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the manage prototype pages independent of the govuk-frontend plugin #2118

Merged
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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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

Expand Down
5 changes: 5 additions & 0 deletions __tests__/spec/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions cypress/e2e/dev/5-management-tests/edit-home-page.cypress.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
})
})
1 change: 0 additions & 1 deletion govuk-prototype-kit.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
Expand Down
8 changes: 2 additions & 6 deletions lib/assets/sass/prototype.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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";
69 changes: 61 additions & 8 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -43,6 +41,8 @@ function generateAssetsSync ({ verbose } = {}) {
const timer = startPerformanceTimer()
plugins.setPluginsByType()
clean()
sassKitFrontendDependency()
sassLegacyPatterns()
sassPlugins()
autoImportComponentsSync()
createBackupNunjucksSync()
Expand Down Expand Up @@ -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)
Expand All @@ -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))

Expand Down
6 changes: 4 additions & 2 deletions lib/manage-prototype-handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,10 @@ function getTemplatesHandler (req, res) {
const availableTemplates = getPluginTemplates()

const commonTemplatesPackageName = '@govuk-prototype-kit/common-templates'
const govUkFrontendPackageName = 'govuk-frontend'
let commonTemplatesDetails
if (!availableTemplates.some(plugin => plugin.packageName === commonTemplatesPackageName)) {
const installedPlugins = plugins.listInstalledPlugins()
if (installedPlugins.includes(govUkFrontendPackageName) && !installedPlugins.includes(commonTemplatesPackageName)) {
commonTemplatesDetails = {
pluginDisplayName: plugins.preparePackageNameForDisplay(commonTemplatesPackageName),
installLink: `${contextPath}/plugins/install?package=${encodeURIComponent(commonTemplatesPackageName)}&returnTo=templates`
Expand Down Expand Up @@ -406,7 +408,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)}`
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/manage-prototype-handlers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ describe('manage-prototype-handlers', () => {
}
}])
plugins.preparePackageNameForDisplay.mockReturnValue(pluginDisplayName)
plugins.listInstalledPlugins.mockReturnValue([])
nunjucksConfiguration.getNunjucksAppEnv.mockImplementation(() => ({
render: () => view
}))
Expand Down
2 changes: 1 addition & 1 deletion lib/nunjucks/govuk-prototype-kit/layouts/unbranded.njk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "govuk-prototype-kit/layouts/govuk-branded.njk" %}
{% extends "govuk/template.njk" %}

{% block headIcons %}
<link rel="shortcut icon" href="/plugin-assets/govuk-prototype-kit/lib/assets/images/unbranded.ico" type="image/x-icon" />
Expand Down
8 changes: 4 additions & 4 deletions lib/nunjucks/views/manage-prototype/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
<h2 class="govuk-heading-m">
Start a new prototype
</h2>
<ul class="app-task-list__items govuk-prototype-kit-manage-prototype-task-list__items">
<ul class="govuk-prototype-kit-manage-prototype-task-list__items govuk-prototype-kit-manage-prototype-task-list__items">
{% for task in tasks %}
<li class="app-task-list__item">
<span class="app-task-list__task-name">
<li class="govuk-prototype-kit-manage-prototype-task-list__item">
<span class="govuk-prototype-kit-manage-prototype-task-list__task-name">
{{ task.html | safe }}
</span>
<strong class="govuk-tag govuk-prototype-kit-manage-prototype-govuk-tag app-task-list__tag">
<strong class="govuk-tag govuk-prototype-kit-manage-prototype-govuk-tag govuk-prototype-kit-manage-prototype-task-list__tag">
{% if task.done %}Done{% else %}To do{% endif %}
</strong>
</li>
Expand Down
Loading