docs(aio): add NOTES
This commit is contained in:
parent
93c0ab7131
commit
c2e672cd1c
|
@ -0,0 +1,159 @@
|
|||
# Design Notes
|
||||
|
||||
## Application State
|
||||
|
||||
Apart from loading up the navigation and search data, there is only one significant state in the app, which is the document being viewed.
|
||||
Other state, such as highlighting the current navigation items and bread crumbs can be derived from that state.
|
||||
The simplest indication of this state is the current `Location#path`, which acts as the single point of truth in the application.
|
||||
|
||||
* The document to display is computed from the `path`.
|
||||
* Navigation to display different documents is achieved by updating the `path`.
|
||||
* Whether a navigation item should be highlighted as active is computed from the `path`
|
||||
|
||||
Navigation between documents can be achieved through changes to the `Location`.
|
||||
|
||||
## Concepts
|
||||
|
||||
There are three main concepts in the application: documents, navigation and search.
|
||||
|
||||
* The document data includes the contents of the document for rendering.
|
||||
* The search data includes keywords used for building the search index.
|
||||
* The navigation data contains information about the visual trees that can be rendered in the app to navigate to the documents.
|
||||
|
||||
### Documents
|
||||
|
||||
Information about documents to be displayed are provided as data that can be fetched from the server.
|
||||
There are two parts to the data for each document: `DocumentContents`.
|
||||
|
||||
* `DocumentContents` contains the actual document that will be rendered. This can be loaded (and then cached) lazily only when the document is to be viewed.
|
||||
|
||||
Each document is uniquely identified by the `path` that is also used to fetch its `DocumentContents`.
|
||||
The `DocumentContents` are stored in JSON files on the server. They are loaded lazily on demand and then cached.
|
||||
|
||||
```ts
|
||||
interface DocumentContents {
|
||||
title: string;
|
||||
contents: string;
|
||||
}
|
||||
|
||||
type DocumentContentsJSONFile = Array<DocumentContents>;
|
||||
```
|
||||
|
||||
### Navigation
|
||||
|
||||
Within an application there can be multiple navigational views for displaying links to documents.
|
||||
For example, there might be views for the top level `Toolbar` and for the more detailed `SideBar` navigation.
|
||||
|
||||
Each view is represented as a tree of `NavigationNode`s. Each `NavigationNode` may, optionally, have a `url`, a `path` and `children`.
|
||||
|
||||
```ts
|
||||
interface NavigationNode {
|
||||
title: string;
|
||||
url?: string;
|
||||
path?: string;
|
||||
tooltip?: string;
|
||||
target?: string;
|
||||
children?: NavigationNode[];
|
||||
}
|
||||
```
|
||||
|
||||
The `url` property represents a link to an external url outside of the app.
|
||||
The `path` property identifies the document to display for this navigation `url`. It is used both as the URL segment in the browser and in the request to fetch the document contents.
|
||||
It is not valid to have both `url` and `path` properties on a single node.
|
||||
If neither `url` nor `path` properties are then the node is a pure container, in which case it ought to have
|
||||
|
||||
The `NavigationNode` data is stored in a JSON file that is fetched from the server at startup
|
||||
|
||||
```ts
|
||||
interface NavigationViews {
|
||||
[name: string]: NavigationNode;
|
||||
}
|
||||
```
|
||||
|
||||
The mapping of a URL back to `NavigationNode` is computed by inverting all the `NavigationNode` structures to produce a `NavigationMap` of URL to node.
|
||||
|
||||
```ts
|
||||
interface NavigationMap {
|
||||
[url: string]: NavigationMapItem
|
||||
}
|
||||
```
|
||||
|
||||
Each `NavigationMapItem` contains information for updating the current navigation views and also caches the `DocumentContents` once it has been loaded.
|
||||
|
||||
```ts
|
||||
interface NavigationMapItem {
|
||||
node: NavigationNode;
|
||||
parents: NavigationNode[];
|
||||
document?: DocumentContents;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Search
|
||||
|
||||
The `SearchTerms` are stored in a single JSON file that is loaded by the search WebWorker at startup and used to generate the search index.
|
||||
|
||||
```ts
|
||||
interface SearchTerms {
|
||||
url: string;
|
||||
title: string;
|
||||
body: string;
|
||||
}
|
||||
|
||||
type SearchTermsJSONFile = Array<SearchTerms>;
|
||||
```
|
||||
|
||||
## LocationService
|
||||
|
||||
Since the core Angular `Location` service does not expose a subject, nor emits events when the location is changed programmatically,
|
||||
we have our own `LocationService` that does this for us.
|
||||
|
||||
```
|
||||
export class LocationService {
|
||||
currentUrl: Observable<string>;
|
||||
go(url: string): void
|
||||
}
|
||||
```
|
||||
|
||||
You can subscribe to the `currentUrl` to be updated when location changes occur.
|
||||
You should navigate to new documents by calling `go`.
|
||||
|
||||
## DocumentService
|
||||
|
||||
The `DocumentService` is responsible for monitoring the `LocationService.currentUrl` and updating the `currentDocument`.
|
||||
When the `currentUrl` changes, the `DocumentService` will fetch the `DocumentContents` from the server if necessary and cache it for the future.
|
||||
|
||||
```ts
|
||||
export class DocumentService {
|
||||
currentDocument: Observable<DocumentContents>;
|
||||
}
|
||||
```
|
||||
|
||||
The mapping of URL path to the path to fetch the document contents is simply:
|
||||
|
||||
```ts
|
||||
private computePath(url) {
|
||||
url = url.startsWith('/') ? url : '/' + url;
|
||||
return 'content/docs' + url + '.json';
|
||||
}
|
||||
```
|
||||
|
||||
## NavigationService
|
||||
|
||||
The `NavigationService` is responsible for:
|
||||
|
||||
* fetching and exposing the `NavigationViews` for use in displaying navigation UI.
|
||||
* building the `NavigationMap` from the `NavigationNode` data.
|
||||
* updating observables for the currently active `NavigationNode`s that can be used to render the navigation UI
|
||||
when the `LocationService.currentUrl` changes.
|
||||
|
||||
|
||||
```ts
|
||||
class NavigationService {
|
||||
navigationViews: Observable<NavigationViews>;
|
||||
currentNode: Observable<NavigationNode>;
|
||||
activeNodes: Observable<NavigationNode[]>;
|
||||
}
|
||||
```
|
||||
|
Loading…
Reference in New Issue