I'm following the Carbon Design System Angular Tutorial. I'm trying to increment the repositories page implemented during the tutorial. My goal is to use the 'with toolbar' from table angular stories.
I'm facing these runtime property's binding errors regarding the ibm-table-toolbar and ibm-overflow-menu. See the image below:
repositories.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RepositoriesRoutingModule } from './repositories-routing.module';
import { RepoPageComponent } from './repo-page/repo-page.component';
import {
GridModule,
TableModule,
SearchModule,
LinkModule,
PaginationModule,
PanelModule,
ToggleModule,
ButtonModule,
DialogModule,
NFormsModule
} from 'carbon-components-angular';
import {
SettingsModule,
DeleteModule,
FilterModule,
SaveModule,
DownloadModule,
AddModule
} from '@carbon/icons-angular';
import { RepoTableComponent } from './repo-table/repo-table.component';
// import { Button } from 'protractor';
@NgModule({
declarations: [RepoPageComponent, RepoTableComponent],
imports: [
CommonModule,
RepositoriesRoutingModule,
GridModule,
TableModule,
LinkModule,
PaginationModule,
PanelModule,
ToggleModule,
ButtonModule,
SettingsModule,
DeleteModule,
FilterModule,
SaveModule,
DownloadModule,
AddModule,
SearchModule,
FormsModule,
DialogModule,
NFormsModule
]
})
export class RepositoriesModule { }
repo-table.component.html
<ibm-table-container>
<ibm-table-header>
<h4 ibmTableHeaderTitle>Carbon Repositories</h4>
<p ibmTableHeaderDescription>A collection of public Carbon repositories.</p>
</ibm-table-header>
<ibm-table-toolbar [model]="model" [batchText]="null" [size]="md" (cancel)="cancelMethod()" #toolbar>
<ibm-table-toolbar-actions>
<button ibmButton="primary" [tabindex]="toolbar.selected ? 0 : -1">
Delete
<ibm-icon-delete size="16" class="bx--btn__icon"></ibm-icon-delete>
</button>
<button ibmButton="primary" [tabindex]="toolbar.selected ? 0 : -1">
Save
<ibm-icon-save size="16" class="bx--btn__icon"></ibm-icon-save>
</button>
<button ibmButton="primary" [tabindex]="toolbar.selected ? 0 : -1">
Download
<ibm-icon-download size="16" class="bx--btn__icon"></ibm-icon-download>
</button>
</ibm-table-toolbar-actions>
<ibm-table-toolbar-content *ngIf="!toolbar.selected">
<ibm-table-toolbar-search ngDefaultControl [expandable]="true" [(ngModel)]="searchModel">
</ibm-table-toolbar-search>
<ibm-overflow-menu triggerClass="bx--toolbar-action" [customTrigger]="customTrigger" placement="bottom"
[offset]="size === 'sm' ? null : offset">
<ibm-overflow-menu-option>Option 1</ibm-overflow-menu-option>
<ibm-overflow-menu-option>Option 2</ibm-overflow-menu-option>
<ibm-overflow-menu-option disabled="true">Disabled</ibm-overflow-menu-option>
<ibm-overflow-menu-option type="danger">Danger option</ibm-overflow-menu-option>
</ibm-overflow-menu>
<button ibmButton="primary" size="sm" [tabindex]="toolbar.selected ? -1 : 0">
Primary button<ibm-icon-add size="20" class="bx--btn__icon"></ibm-icon-add>
</button>
</ibm-table-toolbar-content>
</ibm-table-toolbar>
<ibm-table [skeleton]="skeleton" [model]="skeleton ? skeletonModel : model" [showSelectionColumn]="true">
</ibm-table>
<ibm-pagination [model]="model" (selectPage)="selectPage($event)"></ibm-pagination>
</ibm-table-container>
<ng-template #linkTemplate let-data="data">
<ul style="display: flex">
<li>
<a ibmLink [href]="data.github">Github</a>
</li>
<li *ngIf="data.homepage">
<span> | </span>
<a ibmLink [href]="data.homepage">HomePage</a>
</li>
</ul>
</ng-template>
<ibm-panel [expanded]="showSidePanel">
<ibm-toggle [label]="Teste" [checked]="showSidePanel" (change)="toggleSideBarVisibility()">
</ibm-toggle>
</ibm-panel>
repo-table.component.ts
import {
Component,
OnInit,
ViewChild,
TemplateRef
} from '@angular/core';
import {
Table,
TableModel,
TableItem,
TableHeaderItem,
} from 'carbon-components-angular';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';
@Component({
selector: 'app-repo-table',
templateUrl: './repo-table.component.html',
styleUrls: ['./repo-table.component.scss']
})
export class RepoTableComponent implements OnInit {
data = [];
model: TableModel;
skeletonModel = Table.skeletonModel(10, 6);
skeleton = true;
showSidePanel = false;
searchModel = '';
batchText = {
"SINGLE": "1 item selected",
"MULTIPLE": "{{count}} items selected"
};
size = 'md';
@ViewChild('linkTemplate', null)
protected linkTemplate: TemplateRef<any>;
constructor(private apollo: Apollo) { }
ngOnInit() {
this.model = new TableModel();
this.model.header = [
new TableHeaderItem({data: 'Name'}),
new TableHeaderItem({data: 'Created'}),
new TableHeaderItem({data: 'Updated'}),
new TableHeaderItem({data: 'Open Issues'}),
new TableHeaderItem({data: 'Stars'}),
new TableHeaderItem({data: 'Links'})
];
this.apollo.watchQuery({
query: gql`
query REPO_QUERY {
# Let's use carbon as our organization
organization(login: "carbon-design-system") {
# We'll grab all the repositories in one go. To load more resources
# continuously, see the advanced topics.
repositories(first: 75, orderBy: { field: UPDATED_AT, direction: DESC }) {
totalCount
nodes {
url
homepageUrl
issues(filterBy: { states: OPEN }) {
totalCount
}
stargazers {
totalCount
}
releases(first: 1) {
totalCount
nodes {
name
}
}
name
updatedAt
createdAt
description
id
}
}
}
}
`
})
.valueChanges.subscribe((response: any) => {
if (response.error) {
const errorData = [];
errorData.push([
new TableItem({data: 'error!' })
]);
this.model.data = errorData;
} else if (response.loading) {
this.skeleton = true;
} else {
// If we're here, we've got our data!
this.data = response.data.organization.repositories.nodes;
this.model.pageLength = 10;
this.model.totalDataLength = response.data.organization.repositories.totalCount;
this.selectPage(1);
}
});
}
selectPage(page) {
const offset = this.model.pageLength * (page - 1);
const pageRawData = this.data.slice(offset, offset + this.model.pageLength);
this.model.data = this.prepareData(pageRawData);
this.model.currentPage = page;
}
prepareData(data) {
this.skeleton = false;
const newData = [];
for (const datum of data) {
newData.push([
new TableItem({ data: datum.name/* , expandedData: datum.description */}),
new TableItem({ data: new Date(datum.createdAt).toLocaleDateString() }),
new TableItem({ data: new Date(datum.updatedAt).toLocaleDateString() }),
new TableItem({ data: datum.issues.totalCount }),
new TableItem({ data: datum.stargazers.totalCount }),
new TableItem({
data: {
github: datum.url,
homepage: datum.homepageUrl
},
template: this.linkTemplate
})
]);
}
return newData;
}
toggleSideBarVisibility() {
this.showSidePanel = !this.showSidePanel;
}
}
My forked repo of the tutorial with the branch trying to implement the increments.
I'm trying to understand what I'm doing wrong. I think is regarding imports and declarations... I'm really lost about these.
This is what I see on VSCode, after installing some plugins for angular.
Also, the IntelliSense suggests this:
Can't bind to 'size' since it isn't a known property of 'ibm-table-toolbar'.
- If 'ibm-table-toolbar' is an Angular component and it has 'size' input, > then verify that it is part of this module.
- If 'ibm-table-toolbar' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
- To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.
After few days of smashing my keyboard with my own head. I've finally got an insight, and decide to further investigate the code of the problematic components (on my local node modules). Of course, these attributes are not expected, because of the version I were installed. So in the end was only a matter of updating the carbon angular components dependecy.