Repository navigation
Extended Project Pages
An extended project page is a project page whose masthead, summary panel, tab strip and tab
content come from a content file in eagle-public instead of only from the project record. It
applies to the react line of eagle-public. Pacific Link is the one project that has one. Every
other project keeps the standard page.
A project gets an extended page when the runtime config key EXTENDED_PROJECT_PAGES maps its id to
a content key. The key is empty by default, so no project has one. For the key's shape and limits,
and for the steps that switch a page off, see
Configuration Management.
A content key that has no entry in EXTENDED_CONTENT leaves the project on the standard page.
Content is a TypeScript file in eagle-public, edited by a developer:
src/app/pages/project/extended/content/<key>.ts. The file exports one ExtendedPage object
(types.ts). The object is plain data: no functions, dates or class instances. Each file is
registered under its content key in EXTENDED_CONTENT in extended-page.ts.
The project record still supplies the id, the centroid, the documents and a fallback description. The Act a project falls under comes from the record, see Project Data Models.
Every part is optional. A part that is absent is not drawn, and the standard piece stays.
| Part | What it does | Falls back to |
|---|---|---|
version |
Must be 1. Required |
|
displayName |
Replaces the project name in the masthead, breadcrumb and tab strip | Record name |
masthead.badge |
Gold pill above the title | No pill |
masthead.subLine |
Lines joined with " · " under the title | Proponent and location from the record |
masthead.actions |
External links shown after Subscribe, in order | The Short link action |
panel.timeline |
Draws the page's timeline in the progress slot of the summary panel. Needs timeline
|
Assessment rail |
panel.facts |
Label and value rows in the summary panel. statusDot puts a dot before a value |
Status, EA decision, Type, Location and Proponent from the record |
panel.map |
Thumbnail of map, with an accessible name and a caption. Needs map
|
Location map |
timeline |
Title, note, steps and currentStep. Read by panel.timeline and by the timeline block |
None |
map |
GeoJSON URL, labelled lines and places. Read by panel.map and by the routeMap block |
None |
updates |
Updates from other governments, linked to their source. Read by the updates block and by a tab's count: 'updates'
|
The updates tab reads the record's updates |
tabs |
The tab strip. See Tabs | The standard tabs |
documents.empty |
Notice shown in place of an empty EPIC documents table | The standard empty table |
documents.external |
Documents other governments publish, grouped by publisher and linked where they are hosted. Shown on the Documents tab. An empty groups leaves the section out |
None |
autoLinks |
Terms linked on their first mention in each piece of running copy. cited links the term elsewhere when the copy also mentions a given string |
Copy is not linked |
currentStep is an index into timeline.steps. A value equal to the number of steps marks every
step complete.
A project under an Act whose stages is none has no assessment rail. See
Project Data Models.
tabs, when present, is the whole tab strip, in the order written. Rules:
- A standard entry is
{ segment: 'overview' }and similar. The segments areoverview,updates,engagement,documents,decisionsandcompliance. The tab is drawn as it is. - A standard tab that
tabsdoes not list is not in the strip. Its URL redirects to Overview. -
tabsmust have anoverviewentry. - An entry with
mainblocks onoverviewand withoutreplaceadds its blocks to the standard Overview.bannerblocks go full width between the strip and the tab.mainblocks follow the standard main column.asideblocks follow the standard side column. - An entry with
replace: trueon any standard segment draws the content tab instead of the standard one. Onlyoverviewmay append; every other standard segment needsreplaceto carry blocks. - A custom segment is a tab that exists only on this page, such as
/p/<id>/act. It needsmainblocks. -
labelsets the strip label. Without it the label istitle, then the standard tab's label. -
titleandintrohead the tab.layout: 'wide'widens the main column. -
count: 'updates'shows the number of the page's updates in the strip and hides the tab when there are none.
An unknown path under a project goes to that project's Overview. This holds for every project, extended or not, and for any path below a custom segment. The query string and hash are kept.
Every block has type, an id unique within its tab, and optional heading and framed (draw as
a card). RichText is a string or an array of strings and { text, href } links.
type |
Shows | Main fields |
|---|---|---|
summary |
Description, headline figures and a numbered list |
description, stats[] (label, value), itemsHeading, items[]
|
routeMap |
The page's map, a tile per line, and facts. Needs map
|
optionsHeading, facts[]
|
table |
Named rows with a value on the right |
intro, rows[] (name, note, value), footnote
|
statCards |
Large figures in tiles, each with a source |
cards[] (value, text, source), note
|
updates |
The page's updates: a side card of the newest, or the full list |
shown, tab, intro
|
definitions |
Terms and their definitions |
items[] (term, detail) |
projects |
Other EPIC projects, linked by record id |
items[] (id, name, note) |
links |
Links that leave EPIC |
style (cards, list, compact), items[] (label, href, detail) |
contacts |
Labelled contact links |
items[] (label, link) |
list |
Numbered or bulleted list |
style (numbered, bulleted), intro, items[]
|
steps |
Numbered steps joined by a line |
noteLabel, steps[] (name, detail, note) |
columns |
Bullet lists side by side |
columns[] (heading, items[]) |
prose |
Running copy | text |
timeline |
The page's timeline, one stop per step. Needs timeline
|
None |
band |
Full-width intro with step tiles. Goes in a tab's banner
|
eyebrow, paragraphs[], steps[] (name, short), primary (label, tab), secondary
|
updates with shown draws the side card, and tab names the tab that "See all" opens.
updates without shown draws the full list. band.primary.tab opens another tab of the page.
validateExtendedPage in validate-extended-page.ts returns one line per problem. The test
validate-extended-page.spec.ts runs it on every file in EXTENDED_CONTENT. A page fails when:
- The page holds anything a JSON round trip would change:
undefined, a function, a date, a class instance or a number that is not finite. -
versionis not1. -
panel.timelineis set and there is notimeline, orpanel.mapis set and there is nomap. - A
routeMapblock is used and the page has nomap. -
map.geojsonUrlis not a path on this site. - A map line id is repeated, or the map has more than two lines.
-
timeline.currentStepis not an integer from 0 to the number of steps. -
tabshas nooverviewentry, or lists a segment twice. - A custom segment does not match
^[a-z][a-z0-9-]{0,30}$, or is already a project route:application,certificates,amendments,project-details,commentingorcp. - A custom tab has no
mainblocks. - A standard tab other than
overviewcarries blocks withoutreplace. -
count: 'updates'is set and the page has noupdates. - A block id is repeated within a tab.
- A
bandorupdatesblock names a tab that is not in the strip. - A panel fact label, an update (link plus date) or a contact label within a tab is repeated.
- An
hrefanywhere breaks the link rule.
Every href in content is one of:
| Form | Opens |
|---|---|
https: URL |
A new tab |
mailto: or tel:
|
The same tab |
A path that starts with / and stays on this site |
The same tab |
http:, other schemes, protocol-relative URLs and values with spaces or control characters fail
validation.
- Create
src/app/pages/project/extended/content/<key>.ts. Export anExtendedPagewithversion: 1. The key uses lower-case letters, digits and-. - Import it in
extended-page.tsand add'<key>': <export>toEXTENDED_CONTENT. - Run the tests. The validation spec covers every registered file.
- Add the project id to
EXTENDED_PROJECT_PAGESfor the environment, as described in Configuration Management.
This page leaves the masthead, panel and timeline standard. It adds one block to the standard
Overview, adds one tab, and leaves Decisions and Compliance out of the strip. It follows
fixtures/ordinary-page.ts.
export const larchCreek: ExtendedPage = {
version: 1,
tabs: [
{
segment: 'overview',
main: [
{
type: 'prose',
id: 'water',
heading: 'Water monitoring',
text: 'Three stations sample Larch Creek each month.',
},
],
},
{ segment: 'updates' },
{
segment: 'community',
label: 'Community fund',
title: 'How the community fund works',
main: [
{
type: 'list',
id: 'rules',
heading: 'Fund rules',
style: 'numbered',
items: ['One grant per group each year.'],
},
],
},
{ segment: 'engagement' },
{ segment: 'documents' },
],
};- Content ships in the public site build. A copy change needs a deploy.
- The route map supports two line colours,
line-1andline-2. - Ordinary project pages load the extended page code with the main bundle. The map library loads only when a route map renders.
Eagle Documentation
Operations
- Deployment Pipeline
- Helm Charts
- Reverse Proxy
- Rollback Procedures
- Eagle Public Release Lines
- Eagle Search Archive
- Azure Migration Strategy
- Azure Hosting
- Front Door Per-App Split
- Front Door Ban Ladder
- Error Logging
- Secrets Management
Architecture
- Architecture Overview
- API Architecture
- Analytics Architecture
- Angular Patterns
- Eagle Public Page Layout
- Eagle Public Adding A Page
- Extended Project Pages
- ENGAGE–EAGLE Integration
- BCGW Project Export
- Eagle Search
- Document Content Search
- Eagle DEMI
- Eagle DEMI Push Sweep
- Eagle DEMI Re-Push and Backfill
- Eagle Notify
- Project Data Models
- Async Jobs API
- Bulk Document Download
Configuration
Help
Repositories
Environments