Skip to content

Commit aa764bb

Browse files
authored
feat(docs,daffio): set full API docs in design component doc (#3635)
1 parent 17c521a commit aa764bb

6 files changed

Lines changed: 110 additions & 10 deletions

File tree

apps/daffio/src/app/docs/design/components/component-content/component-content.component.html

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ <h1>{{doc().title}}</h1>
1313
Usage
1414
</daff-tab-label>
1515
<daff-tab-panel>
16-
<daff-article
16+
<div
1717
[innerHtml]="doc().contents | safe">
18-
</daff-article>
18+
</div>
1919
</daff-tab-panel>
2020
</daff-tab>
2121

@@ -24,9 +24,12 @@ <h1>{{doc().title}}</h1>
2424
API
2525
</daff-tab-label>
2626
<daff-tab-panel>
27-
@for (apiDoc of doc().api; track $index) {
28-
<section [innerHtml]="apiDoc | safe"></section>
29-
<hr>
27+
@for (kv of doc().api | keyvalue | daffioDocsDesignApiSortSectionLabels; track kv.key) {
28+
<h2 [attr.id]="kv.key">{{getSectionLabel(kv.key)}}</h2>
29+
@for (apiDoc of kv.value; track $index) {
30+
<ng-template [ngComponentOutlet]="getApiComponent(apiDoc)" [ngComponentOutletInputs]="{doc: apiDoc, child: true}"></ng-template>
31+
<hr>
32+
}
3033
}
3134
</daff-tab-panel>
3235
</daff-tab>

apps/daffio/src/app/docs/design/components/component-content/component-content.component.spec.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ import { RouterTestingModule } from '@angular/router/testing';
1616
import { DaffTabsComponent } from '@daffodil/design/tabs';
1717
import {
1818
DaffDocKind,
19+
DaffDocsApiRole,
1920
DaffPackageGuideDoc,
2021
} from '@daffodil/docs-utils';
2122

2223
import { DaffioDocsDesignComponentContentComponent } from './component-content.component';
2324
import { DaffioActiveHeaderService } from '../../../../core/dynamic-fragment/service';
25+
import { DaffioDocsApiDefaultContentComponent } from '../../../api/components/api-default-content/api-default-content.component';
26+
import { DaffioDocsApiDynamicContentComponentService } from '../../../api/dynamic-content/dynamic-content-component.service';
2427
import { DaffioDocViewerComponent } from '../../../components/doc-viewer/doc-viewer.component';
2528

2629
@Component({
@@ -51,6 +54,7 @@ describe('DaffioDocsDesignComponentContentComponent', () => {
5154
],
5255
providers: [
5356
DaffioActiveHeaderService,
57+
DaffioDocsApiDynamicContentComponentService,
5458
provideHttpClient(withInterceptorsFromDi()),
5559
provideHttpClientTesting(),
5660
],
@@ -75,7 +79,10 @@ describe('DaffioDocsDesignComponentContentComponent', () => {
7579
lvl: 2,
7680
slug: 'toc',
7781
}],
78-
api: ['<div id="api">api</div>'],
82+
api: {
83+
// TODO: add better test when we have doc factories
84+
[DaffDocsApiRole.COMPONENT]: [<any>{}],
85+
},
7986
contents: '<div id="contents">contents</div>',
8087
longDescription: '<div id="longDescription">longDescription</div>',
8188
breadcrumbs: [],
@@ -122,7 +129,7 @@ describe('DaffioDocsDesignComponentContentComponent', () => {
122129
});
123130

124131
it('should render the api', () => {
125-
expect(fixture.debugElement.query(By.css('#api')).nativeElement.innerText).toEqual('api');
132+
expect(fixture.debugElement.query(By.directive(DaffioDocsApiDefaultContentComponent))).toBeDefined();
126133
});
127134

128135
it('should pass the API toc to the article', () => {

apps/daffio/src/app/docs/design/components/component-content/component-content.component.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import {
2+
KeyValuePipe,
3+
NgComponentOutlet,
4+
} from '@angular/common';
15
import {
26
ChangeDetectionStrategy,
37
Component,
@@ -13,13 +17,17 @@ import {
1317
DaffTabsComponent,
1418
} from '@daffodil/design/tabs';
1519
import {
20+
DaffApiDoc,
1621
DaffDocKind,
22+
daffDocsApiRoleGetSectionLabel,
1723
DaffPackageGuideDoc,
1824
} from '@daffodil/docs-utils';
1925

2026
import { DaffioSafeHtmlPipe } from '../../../../core/html-sanitizer/safe.pipe';
27+
import { DaffioDocsApiDynamicContentComponentService } from '../../../api/dynamic-content/dynamic-content-component.service';
2128
import { DaffioDocViewerComponent } from '../../../components/doc-viewer/doc-viewer.component';
2229
import { DaffioDocsDynamicContent } from '../../../dynamic-content/dynamic-content.type';
30+
import { DaffioDocsDesignApiSortSectionLabels } from '../../pipes/sort-api-section-labels.pipe';
2331

2432
@Component({
2533
selector: 'daffio-docs-design-component-content',
@@ -30,6 +38,9 @@ import { DaffioDocsDynamicContent } from '../../../dynamic-content/dynamic-conte
3038
DAFF_ARTICLE_COMPONENTS,
3139
DaffioDocViewerComponent,
3240
DaffioSafeHtmlPipe,
41+
KeyValuePipe,
42+
DaffioDocsDesignApiSortSectionLabels,
43+
NgComponentOutlet,
3344
],
3445
})
3546
export class DaffioDocsDesignComponentContentComponent implements DaffioDocsDynamicContent<DaffPackageGuideDoc> {
@@ -39,6 +50,7 @@ export class DaffioDocsDesignComponentContentComponent implements DaffioDocsDyna
3950

4051
readonly USAGE_TAB_ID = 'usage-tab';
4152
readonly API_TAB_ID = 'api-tab';
53+
readonly getSectionLabel = daffDocsApiRoleGetSectionLabel;
4254

4355
tabs = viewChild.required(DaffTabsComponent);
4456
doc = input<DaffPackageGuideDoc>();
@@ -53,6 +65,14 @@ export class DaffioDocsDesignComponentContentComponent implements DaffioDocsDyna
5365
}
5466
});
5567

68+
constructor(
69+
private apiComponentService: DaffioDocsApiDynamicContentComponentService,
70+
) {}
71+
72+
getApiComponent(doc: DaffApiDoc) {
73+
return this.apiComponentService.getComponent(doc);
74+
}
75+
5676
setTab(tab: string) {
5777
this._tab.set(tab);
5878
}

apps/daffio/src/app/docs/design/design-routing.module.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { DAFFIO_DOCS_DESIGN_LIST_SIDEBAR_REGISTRATION } from './containers/docs-list/sidebar.provider';
1616
import { DaffioDocsDesignComponentOverviewPageComponent } from './pages/components-overview/component-overview.component';
1717
import { DaffioDocsDesignOverviewPageComponent } from './pages/overview/overview.component';
18+
import { daffioDocsDesignComponentDocResolver } from './services/component-doc.resolver';
1819
import { DaffioRoute } from '../../core/router/route.type';
1920
import { DaffioDocsPageComponent } from '../pages/docs-page/docs-page.component';
2021
import { DocsResolver } from '../resolvers/docs-resolver.service';
@@ -45,7 +46,23 @@ export const docsDesignRoutes: Routes = [
4546
},
4647
{
4748
path: DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.COMPONENT],
48-
component: DaffioDocsDesignComponentOverviewPageComponent,
49+
children: [
50+
{
51+
path: '',
52+
pathMatch: 'full',
53+
component: DaffioDocsDesignComponentOverviewPageComponent,
54+
},
55+
<DaffioRoute>{
56+
path: '**',
57+
component: DaffioDocsPageComponent,
58+
resolve: {
59+
doc: daffioDocsDesignComponentDocResolver,
60+
},
61+
data: {
62+
sidebarMode: DaffSidebarModeEnum.SideFixed,
63+
},
64+
},
65+
],
4966
},
5067
<DaffioRoute>{
5168
path: '**',
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { inject } from '@angular/core';
2+
import {
3+
ActivatedRouteSnapshot,
4+
RedirectCommand,
5+
ResolveFn,
6+
Router,
7+
RouterStateSnapshot,
8+
} from '@angular/router';
9+
import {
10+
switchMap,
11+
combineLatest,
12+
map,
13+
take,
14+
catchError,
15+
of,
16+
} from 'rxjs';
17+
18+
import {
19+
daffUriTruncateLeadingSlash,
20+
daffUriTruncateQueryFragment,
21+
} from '@daffodil/core/routing';
22+
import {
23+
DaffApiDoc,
24+
daffDocsApiArrayToDict,
25+
DaffPackageGuideDoc,
26+
} from '@daffodil/docs-utils';
27+
28+
import { DaffioDocsService } from '../../services/docs.service';
29+
30+
export const daffioDocsDesignComponentDocResolver: ResolveFn<DaffPackageGuideDoc> = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
31+
const docService = inject(DaffioDocsService);
32+
const router = inject(Router);
33+
34+
return docService
35+
//remove any route fragment and initial slash from the route.
36+
.get<DaffPackageGuideDoc>(daffUriTruncateLeadingSlash(daffUriTruncateQueryFragment(state.url)))
37+
.pipe(
38+
switchMap((packageDoc) =>
39+
combineLatest(packageDoc.symbols.map((d) => docService.get<DaffApiDoc>(d))).pipe(
40+
map((apiDocs) => ({
41+
...packageDoc,
42+
api: daffDocsApiArrayToDict(apiDocs),
43+
})),
44+
),
45+
),
46+
take(1),
47+
catchError((err) => of(new RedirectCommand(router.parseUrl('/404'), { skipLocationChange: true }))),
48+
);
49+
};

libs/docs-utils/src/doc/package-guide.type.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { DaffDoc } from './type';
2+
import { DaffDocsApiRole } from '../api/public_api';
23
import { DaffDocTableOfContents } from '../toc/public_api';
4+
import { DaffApiDoc } from './api/public_api';
35

46
/**
57
* A guide doc for a package.
@@ -10,9 +12,11 @@ export interface DaffPackageGuideDoc extends DaffDoc {
1012
*/
1113
symbols: Array<string>;
1214
/**
13-
* A list of rendered API docs.
15+
* A list of API docs.
1416
*/
15-
api: Array<string>;
17+
api: {
18+
[key in DaffDocsApiRole]?: Array<DaffApiDoc>;
19+
};
1620
/**
1721
* A table of contents for the API section.
1822
*/

0 commit comments

Comments
 (0)