diff --git a/greenkeeper.json b/greenkeeper.json
index 8e52839f15..ff6344ebf5 100644
--- a/greenkeeper.json
+++ b/greenkeeper.json
@@ -12,11 +12,5 @@
]
}
},
- "ignore": [
- "@angular/flex-layout",
- "@types/node",
- "class-validator",
- "typescript",
- "tslint-sonarts"
- ]
+ "ignore": ["@angular/flex-layout", "@types/node", "class-validator", "typescript", "tslint-sonarts"]
}
diff --git a/packages/stark-core/src/modules/settings/settings.module.ts b/packages/stark-core/src/modules/settings/settings.module.ts
index 8e4877793f..0198aa75bd 100644
--- a/packages/stark-core/src/modules/settings/settings.module.ts
+++ b/packages/stark-core/src/modules/settings/settings.module.ts
@@ -6,10 +6,7 @@ import { STARK_SETTINGS_SERVICE, StarkSettingsServiceImpl } from "./services";
import { StarkSettingsEffects } from "./effects";
@NgModule({
- imports: [
- StoreModule.forFeature("StarkSettings", starkSettingsReducers),
- EffectsModule.forFeature([StarkSettingsEffects])
- ]
+ imports: [StoreModule.forFeature("StarkSettings", starkSettingsReducers), EffectsModule.forFeature([StarkSettingsEffects])]
})
export class StarkSettingsModule {
/**
diff --git a/packages/stark-ui/assets/styles/_old-variables.scss b/packages/stark-ui/assets/styles/_old-variables.scss
index 103f6f31ef..39d40e42e5 100644
--- a/packages/stark-ui/assets/styles/_old-variables.scss
+++ b/packages/stark-ui/assets/styles/_old-variables.scss
@@ -49,6 +49,7 @@ $md-primary-100: #b2d5ee; /* rgb(178, 213, 238) */
$md-primary: mat-color(map-get($base-theme, primary-palette));
$md-primary-600: mat-color(map-get($base-theme, primary-palette), 600); /* rgb(0, 106, 180) */
$md-primary-700: mat-color(map-get($base-theme, primary-palette), 700); /* rgb(0, 94, 160) */
+$md-primary-alpha-05: rgba(0, 118, 200, 0.05);
$md-primary-alpha-10: rgba(0, 118, 200, 0.1);
$md-primary-alpha-26: rgba(0, 118, 200, 0.26);
$md-primary-alpha-50: rgba(0, 118, 200, 0.5);
@@ -77,3 +78,5 @@ $md-warn-alpha-87: rgba(255, 87, 34, 0.87);
$md-warn-200-alpha-38: rgba(255, 171, 145, 0.38);
$cash2-offwhite: #f6f9fa;
+
+$checkbox-size: 15px;
diff --git a/packages/stark-ui/src/modules.ts b/packages/stark-ui/src/modules.ts
index 70b7e276da..be4d911c5d 100644
--- a/packages/stark-ui/src/modules.ts
+++ b/packages/stark-ui/src/modules.ts
@@ -11,6 +11,7 @@ export * from "./modules/date-range-picker";
export * from "./modules/dropdown";
export * from "./modules/keyboard-directives";
export * from "./modules/language-selector";
+export * from "./modules/minimap";
export * from "./modules/pagination";
export * from "./modules/pretty-print";
export * from "./modules/session-ui";
diff --git a/packages/stark-ui/src/modules/app-menu/components/_app-menu.component.scss b/packages/stark-ui/src/modules/app-menu/components/_app-menu.component.scss
index 35a13fa960..a3ebbd96ac 100644
--- a/packages/stark-ui/src/modules/app-menu/components/_app-menu.component.scss
+++ b/packages/stark-ui/src/modules/app-menu/components/_app-menu.component.scss
@@ -44,4 +44,4 @@
}
}
-/* END stark-ui: src/modules/dropdown/components/dropdown/_dropdown.component.scss */
+/* END stark-ui: src/modules/dropdown/components/app-menu/_app-menu.component.scss */
diff --git a/packages/stark-ui/src/modules/minimap.ts b/packages/stark-ui/src/modules/minimap.ts
new file mode 100644
index 0000000000..762a023587
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap.ts
@@ -0,0 +1,2 @@
+export * from "./minimap/minimap.module";
+export * from "./minimap/components";
diff --git a/packages/stark-ui/src/modules/minimap/components.ts b/packages/stark-ui/src/modules/minimap/components.ts
new file mode 100644
index 0000000000..8fc0adbf67
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components.ts
@@ -0,0 +1,3 @@
+export * from "./components/minimap.component";
+export * from "./components/item-properties.intf";
+export * from "./components/item-visibility.intf";
diff --git a/packages/stark-ui/src/modules/minimap/components/_minimap-theme.scss b/packages/stark-ui/src/modules/minimap/components/_minimap-theme.scss
new file mode 100644
index 0000000000..565efe2b89
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components/_minimap-theme.scss
@@ -0,0 +1,196 @@
+/* ============================================================================== */
+/* S t a r k M i n i m a p */
+/* ============================================================================== */
+/* stark-ui: src/modules/minimap/components/minimap-theme.scss */
+
+.compact-minimap {
+ & .stark-minimap-dots {
+ & i {
+ background-color: $secondary-dark-text-color;
+ opacity: 0.2;
+ }
+ & li.selected i {
+ opacity: 1;
+ }
+ }
+ & .stark-minimap-dropdown-toggle {
+ & .stark-minimap-dropdown-toggle-menu {
+ box-shadow: $elevation-4;
+ & mat-checkbox.mat-checked .mat-icon {
+ background-color: $md-accent;
+ }
+ }
+ & .mat-button.mat-icon-button {
+ & svg {
+ fill: #000;
+ }
+ border: 1px solid mat-color($grey-palette, 300);
+ background-color: $md-primary-alpha-05;
+ }
+ & mat-icon {
+ fill: $md-primary;
+ }
+ & .stark-minimap-dropdown-toggle-menu {
+ border-color: mat-color($grey-palette, 500);
+ box-shadow: 0 1px 2px mat-color($grey-palette, 300);
+ background-color: mat-color($grey-palette, 50);
+ & mat-checkbox {
+ &:hover {
+ background: $md-primary-alpha-05;
+ }
+ & ._mat-icon {
+ &::after {
+ border-color: mat-color($grey-palette, 50);
+ }
+ }
+ & .stark-minimap-dropdown {
+ & mat-checkbox.stark-minimap-column-checkbox {
+ &.mat-checked ._mat-icon {
+ background-color: $md-primary-200-alpha-38;
+ }
+ }
+ }
+ }
+ }
+
+ @media #{$desktop-query} {
+ & .stark-minimap-dropdown-toggle-menu {
+ font-size: 16px;
+ & mat-checkbox {
+ padding: 3px 16px;
+ & ._mat-container {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 10px;
+ left: 16px;
+ }
+ & ._mat-icon {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ }
+ & ._mat-label {
+ width: 100%;
+ padding: 0 0 0 26px;
+ font-size: 12px;
+ & span {
+ max-width: 400px;
+ }
+ }
+ &.mat-checked ._mat-icon::after {
+ width: 8px;
+ height: 10px;
+ top: 2px;
+ left: 4px;
+ }
+ &:first-child {
+ margin-top: 8px;
+ }
+ &:last-child {
+ margin-bottom: 8px;
+ }
+ }
+ }
+ }
+ }
+}
+
+.full-minimap {
+ & .stark-minimap-dots {
+ & i {
+ background-color: $secondary-dark-text-color;
+ opacity: 0.2;
+ }
+ & li.selected i {
+ opacity: 1;
+ }
+ }
+ & .stark-minimap-dropdown-toggle {
+ & .stark-minimap-dropdown-toggle-menu {
+ box-shadow: $elevation-4;
+ & mat-checkbox.mat-checked .mat-icon {
+ background-color: $md-accent;
+ }
+ }
+ & .mat-button.mat-icon-button {
+ & svg {
+ fill: #000;
+ }
+ border: 1px solid mat-color($grey-palette, 300);
+ background-color: $md-primary-alpha-05;
+ }
+ & mat-icon {
+ fill: $md-primary;
+ }
+ & .stark-minimap-dropdown-toggle-menu {
+ border-color: mat-color($grey-palette, 500);
+ box-shadow: 0 1px 2px mat-color($grey-palette, 300);
+ background-color: mat-color($grey-palette, 50);
+ & mat-checkbox {
+ &:hover {
+ background: $md-primary-alpha-05;
+ }
+ & ._mat-icon {
+ &::after {
+ border-color: mat-color($grey-palette, 50);
+ }
+ }
+ & .stark-minimap-dropdown {
+ & mat-checkbox.stark-minimap-column-checkbox {
+ &.mat-checked ._mat-icon {
+ background-color: $md-primary-200-alpha-38;
+ }
+ }
+ }
+ }
+ }
+
+ @media #{$desktop-query} {
+ & .stark-minimap-dropdown-toggle-menu {
+ font-size: 16px;
+ & mat-checkbox {
+ padding: 3px 16px;
+ & ._mat-container {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 10px;
+ left: 16px;
+ }
+ & ._mat-icon {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ }
+ & ._mat-label {
+ width: 100%;
+ padding: 0 0 0 26px;
+ font-size: 12px;
+ & span {
+ max-width: 400px;
+ }
+ }
+ &.mat-checked ._mat-icon::after {
+ width: 8px;
+ height: 10px;
+ top: 2px;
+ left: 4px;
+ }
+ &:first-child {
+ margin-top: 8px;
+ }
+ &:last-child {
+ margin-bottom: 8px;
+ }
+ }
+ }
+ }
+ }
+}
+
+.stark-table {
+ & .stark-minimap {
+ & .stark-minimap-dropdown-toggle .stark-minimap-dropdown-toggle-menu {
+ box-shadow: $elevation-2;
+ }
+ }
+}
+
+/* End stark-ui: src/modules/minimap/components/minimap-theme.scss */
diff --git a/packages/stark-ui/src/modules/minimap/components/_minimap.component.scss b/packages/stark-ui/src/modules/minimap/components/_minimap.component.scss
new file mode 100644
index 0000000000..d1a90d8e67
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components/_minimap.component.scss
@@ -0,0 +1,373 @@
+/* ============================================================================== */
+/* S t a r k M i n i m a p */
+/* ============================================================================== */
+/* stark-ui: src/modules/minimap/components/minimap.component.scss */
+
+.compact-minimap {
+ display: flex;
+ flex-flow: row wrap;
+ flex-grow: 1;
+ align-items: flex-start;
+ justify-content: flex-start;
+ padding-top: 8px;
+ margin: 0 15px;
+ & .stark-minimap-dots {
+ & ul {
+ margin: 0 8px 0 0;
+ padding: 0;
+ }
+ & li {
+ display: inline-block;
+ margin: 0;
+ padding: 0 3px 0;
+ line-height: 18px;
+ vertical-align: top;
+ }
+ & i {
+ display: inline-block;
+ width: 4px;
+ height: 4px;
+ opacity: 0.2;
+ }
+ & li.selected i {
+ opacity: 1;
+ }
+ }
+ & .stark-minimap-dropdown-toggle {
+ position: relative;
+ margin: 0;
+ padding-top: 0;
+ & .stark-minimap-dropdown-toggle-menu {
+ font-size: 14px;
+ border: 0;
+ min-width: 180px;
+ & mat-checkbox .mat-label {
+ margin-left: 40px;
+ font-size: 12px;
+ }
+ }
+ & .mat-button.mat-icon-button {
+ height: auto;
+ margin: 0;
+ transform: translateY(-8px);
+ }
+ & .mat-icon-button .up {
+ display: none;
+ }
+ &.visible {
+ & .stark-minimap-dropdown-toggle-menu {
+ display: block;
+ }
+ & .down {
+ display: none;
+ }
+ & .up {
+ display: inline-block;
+ }
+ }
+ & .stark-minimap-dropdown-toggle-button {
+ min-height: 0;
+ margin: 0;
+ padding: 0 2px 0 0;
+ }
+ & .stark-minimap-dropdown-toggle-menu {
+ position: absolute;
+ z-index: 1;
+ top: 27px;
+ right: 0;
+ display: none;
+ padding: 0;
+ border-radius: 2px;
+ font-size: 16px;
+ & mat-checkbox {
+ display: block;
+ min-width: 0;
+ min-height: 0;
+ margin: 0;
+ padding: 4px 8px 5px;
+ & ._mat-container {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 13px;
+ left: 8px;
+ }
+ & ._mat-icon {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 5px;
+ }
+ & ._mat-label {
+ width: 100%;
+ margin: 0;
+ padding: 0 0 0 20px;
+ & span {
+ display: block;
+ max-width: 260px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ }
+ &.mat-checked ._mat-icon::after {
+ width: 6px;
+ height: 8px;
+ top: 3px;
+ left: 4px;
+ }
+ &:first-child {
+ margin-top: 4px;
+ }
+ &:last-child {
+ margin-bottom: 4px;
+ }
+ }
+ & .stark-minimap-dropdown {
+ & .mat-container {
+ left: 16px;
+ }
+ & mat-checkbox.stark-minimap-column-checkbox {
+ & ._mat-icon {
+ border-width: 1px;
+ }
+ }
+ }
+ }
+ }
+
+ @media #{$desktop-query} {
+ & .stark-minimap-dropdown-toggle-menu {
+ font-size: 16px;
+ & mat-checkbox {
+ padding: 3px 16px;
+ & ._mat-container {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 10px;
+ left: 16px;
+ }
+ & ._mat-icon {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ }
+ & ._mat-label {
+ width: 100%;
+ padding: 0 0 0 26px;
+ font-size: 12px;
+ & span {
+ max-width: 400px;
+ }
+ }
+ &.mat-checked ._mat-icon::after {
+ width: 8px;
+ height: 10px;
+ top: 2px;
+ left: 4px;
+ }
+ &:first-child {
+ margin-top: 8px;
+ }
+ &:last-child {
+ margin-bottom: 8px;
+ }
+ }
+ }
+ }
+}
+
+.full-minimap {
+ display: flex;
+ flex-flow: row wrap;
+ flex-grow: 1;
+ align-items: flex-start;
+ justify-content: flex-start;
+ padding-top: 8px;
+ margin: 0 15px;
+ & .stark-minimap-dots {
+ & ul {
+ margin: 0 8px 0 0;
+ padding: 0;
+ }
+ & li {
+ display: inline-block;
+ margin: 0;
+ padding: 0 3px 0;
+ line-height: 18px;
+ vertical-align: top;
+ }
+ & i {
+ display: inline-block;
+ width: 4px;
+ height: 4px;
+ opacity: 0.2;
+ }
+ & li.selected i {
+ opacity: 1;
+ }
+ }
+ & .stark-minimap-dropdown-toggle {
+ position: relative;
+ margin: 0;
+ padding-top: 0;
+ & .stark-minimap-dropdown-toggle-menu {
+ font-size: 14px;
+ border: 0;
+ min-width: 180px;
+ & mat-checkbox .mat-label {
+ margin-left: 40px;
+ font-size: 12px;
+ }
+ }
+ & .mat-button.mat-icon-button {
+ height: auto;
+ margin: 0;
+ transform: translateY(-8px);
+ }
+ & .mat-icon-button .up {
+ display: none;
+ }
+ &.visible {
+ & .stark-minimap-dropdown-toggle-menu {
+ display: block;
+ }
+ & .down {
+ display: none;
+ }
+ & .up {
+ display: inline-block;
+ }
+ }
+ & .stark-minimap-dropdown-toggle-button {
+ min-height: 0;
+ margin: 0;
+ padding: 0 2px 0 0;
+ }
+ & .stark-minimap-dropdown-toggle-menu {
+ position: absolute;
+ z-index: 1;
+ top: 27px;
+ right: 0;
+ display: none;
+ padding: 0;
+ border-radius: 2px;
+ font-size: 16px;
+ & mat-checkbox {
+ display: block;
+ min-width: 0;
+ min-height: 0;
+ margin: 0;
+ padding: 4px 8px 5px;
+ & ._mat-container {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 13px;
+ left: 8px;
+ }
+ & ._mat-icon {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 5px;
+ }
+ & ._mat-label {
+ width: 100%;
+ margin: 0;
+ padding: 0 0 0 20px;
+ & span {
+ display: block;
+ max-width: 260px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ }
+ &.mat-checked ._mat-icon::after {
+ width: 6px;
+ height: 8px;
+ top: 3px;
+ left: 4px;
+ }
+ &:first-child {
+ margin-top: 4px;
+ }
+ &:last-child {
+ margin-bottom: 4px;
+ }
+ }
+ & .stark-minimap-dropdown {
+ & .mat-container {
+ left: 16px;
+ }
+ & mat-checkbox.stark-minimap-column-checkbox {
+ & ._mat-icon {
+ border-width: 1px;
+ }
+ }
+ }
+ }
+ }
+
+ @media #{$desktop-query} {
+ & .stark-minimap-dropdown-toggle-menu {
+ font-size: 16px;
+ & mat-checkbox {
+ padding: 3px 16px;
+ & ._mat-container {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ top: 10px;
+ left: 16px;
+ }
+ & ._mat-icon {
+ width: $checkbox-size;
+ height: $checkbox-size;
+ }
+ & ._mat-label {
+ width: 100%;
+ padding: 0 0 0 26px;
+ font-size: 12px;
+ & span {
+ max-width: 400px;
+ }
+ }
+ &.mat-checked ._mat-icon::after {
+ width: 8px;
+ height: 10px;
+ top: 2px;
+ left: 4px;
+ }
+ &:first-child {
+ margin-top: 8px;
+ }
+ &:last-child {
+ margin-bottom: 8px;
+ }
+ }
+ }
+ }
+}
+
+.stark-table {
+ & .stark-minimap-dropdown-toggle-menu {
+ padding-right: 16px;
+ }
+ & .stark-table-action-bar {
+ & .stark-minimap-dropdown-toggle-button {
+ & mat-icon {
+ width: 20px;
+ height: 20px;
+ }
+ }
+ }
+ & .stark-minimap {
+ padding-top: 0;
+ & .stark-minimap-dropdown-toggle .mat-button.mat-icon-button {
+ transform: none;
+ }
+ & .stark-minimap-dropdown-toggle .stark-minimap-dropdown-toggle-menu {
+ font-size: 14px;
+ border: 0;
+ min-width: 180px;
+ }
+ }
+}
+
+/* END stark-ui: src/modules/minimap/components/minimap.component.scss */
diff --git a/packages/stark-ui/src/modules/minimap/components/item-properties.intf.ts b/packages/stark-ui/src/modules/minimap/components/item-properties.intf.ts
new file mode 100644
index 0000000000..5635504787
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components/item-properties.intf.ts
@@ -0,0 +1,14 @@
+/**
+ * Represents the properties of an item inside the Stark Minimap component.
+ */
+export interface StarkMinimapItemProperties {
+ /**
+ * The name of the item
+ */
+ name: string;
+
+ /**
+ * The label of the item (optional). If not provided, then the name of the item will be used.
+ */
+ label?: string;
+}
diff --git a/packages/stark-ui/src/modules/minimap/components/item-visibility.intf.ts b/packages/stark-ui/src/modules/minimap/components/item-visibility.intf.ts
new file mode 100644
index 0000000000..cc1ad68b4f
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components/item-visibility.intf.ts
@@ -0,0 +1,17 @@
+import { StarkMinimapItemProperties } from "./item-properties.intf";
+
+/**
+ * Indicates if a item is visible or not
+ */
+export interface ItemVisibility {
+ /**
+ * is the item visible
+ */
+ isVisible: boolean;
+
+ /**
+ * the item to display/hide
+ */
+
+ item: StarkMinimapItemProperties;
+}
diff --git a/packages/stark-ui/src/modules/minimap/components/minimap.component.html b/packages/stark-ui/src/modules/minimap/components/minimap.component.html
new file mode 100644
index 0000000000..4462ab66af
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components/minimap.component.html
@@ -0,0 +1,55 @@
+
+
+
+
+
diff --git a/packages/stark-ui/src/modules/minimap/components/minimap.component.spec.ts b/packages/stark-ui/src/modules/minimap/components/minimap.component.spec.ts
new file mode 100644
index 0000000000..a6b097b895
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components/minimap.component.spec.ts
@@ -0,0 +1,136 @@
+//tslint:disable:no-commented-code completed-docs
+import { StarkMinimapComponent } from "./minimap.component";
+import { StarkMinimapItemProperties } from "./item-properties.intf";
+import createSpyObj = jasmine.createSpyObj;
+import SpyObj = jasmine.SpyObj;
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
+import { FormsModule } from "@angular/forms";
+import { NoopAnimationsModule } from "@angular/platform-browser/animations";
+import { TranslateModule, TranslateService } from "@ngx-translate/core";
+import { STARK_LOGGING_SERVICE } from "@nationalbankbelgium/stark-core";
+import { MockStarkLoggingService } from "@nationalbankbelgium/stark-core/testing";
+import { Component, EventEmitter, NO_ERRORS_SCHEMA, ViewChild } from "@angular/core";
+import { MatCheckboxModule } from "@angular/material/checkbox";
+import { MatTooltipModule } from "@angular/material/tooltip";
+import { ItemVisibility } from "@nationalbankbelgium/stark-ui";
+
+@Component({
+ selector: `host-component`,
+ template: ``
+})
+class TestHostComponent {
+ @ViewChild(StarkMinimapComponent)
+ public minimapComponent: StarkMinimapComponent;
+ public items: StarkMinimapItemProperties[];
+ public visibleItems: string[];
+}
+
+/* tslint:disable:no-big-function */
+describe("MinimapComponent", () => {
+ let component: StarkMinimapComponent;
+ let hostComponent: TestHostComponent;
+ let hostFixture: ComponentFixture;
+ let defaultItem: StarkMinimapItemProperties;
+ let defaultItemVisibility: ItemVisibility;
+
+ beforeEach(async(() => {
+ return TestBed.configureTestingModule({
+ imports: [FormsModule, MatCheckboxModule, MatTooltipModule, NoopAnimationsModule, TranslateModule.forRoot()],
+ declarations: [StarkMinimapComponent, TestHostComponent],
+ providers: [{ provide: STARK_LOGGING_SERVICE, useValue: new MockStarkLoggingService() }, TranslateService],
+ schemas: [NO_ERRORS_SCHEMA] // to avoid errors due to "mat-icon" directive not known (which we don't want to add in these tests)
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ hostFixture = TestBed.createComponent(TestHostComponent);
+ hostComponent = hostFixture.componentInstance;
+ hostFixture.detectChanges();
+
+ component = hostComponent.minimapComponent;
+ });
+
+ describe("on initialization", () => {
+ it("should set internal component properties", () => {
+ expect(hostFixture).toBeDefined();
+ expect(component).toBeDefined();
+
+ expect(component.logger).not.toBeNull();
+ expect(component.logger).toBeDefined();
+ expect(component.items).toBeUndefined();
+ expect(component.visibleItems).toBeUndefined();
+ });
+ });
+
+ describe("toggleDropdownMenu", () => {
+ it("should set TRUE if customMenu is displayed", () => {
+ component.isDisplayedMenu = false;
+ component.toggleDropdownMenu();
+ expect(component.isDisplayedMenu).toBe(true);
+ });
+
+ it("should set FALSE if customMenu is hidden", () => {
+ component.isDisplayedMenu = true;
+ component.toggleDropdownMenu();
+ expect(component.isDisplayedMenu).toBe(false);
+ });
+ });
+
+ describe("getItemLabel", () => {
+ it("should return the label of item when it is declared in minimapItemsProperties", () => {
+ const getItemLabel: string = component.getItemLabel({ name: "column1", label: "Test label" });
+ expect(getItemLabel).toEqual("Test label");
+ });
+
+ it("should return the item name of item when it is not declared in minimapItemsProperties", () => {
+ const getItemLabel: string = component.getItemLabel({ name: "column2" });
+ expect(getItemLabel).toEqual("column2");
+ });
+ });
+
+ describe("isItemVisible", () => {
+ beforeEach(() => {
+ component.items = [];
+ component.visibleItems = [];
+ defaultItem = {
+ name: "item"
+ };
+ });
+
+ it("should return FALSE if item is NOT present in visibleItems array", () => {
+ const isVisibleColumn: boolean = component.isItemVisible(defaultItem);
+ expect(isVisibleColumn).toBe(false);
+ });
+
+ it("should return TRUE if item is present in visibleItems array", () => {
+ component.visibleItems.push(defaultItem.name);
+ const isVisibleColumn: boolean = component.isItemVisible(defaultItem);
+ expect(isVisibleColumn).toBe(true);
+ });
+ });
+
+ describe("triggerShowHideItem", () => {
+ beforeEach(() => {
+ defaultItem = {
+ name: "item"
+ };
+ defaultItemVisibility = {
+ isVisible: true,
+ item: {
+ name: "item"
+ }
+ };
+ });
+
+ it("should trigger the callback showHideItem method with item as argument if callback is defined", () => {
+ const showHideItemSpy: SpyObj> = createSpyObj("showHideItem", ["emit"]);
+ component.items = [];
+ component.visibleItems = [];
+ component.showHideItem = showHideItemSpy;
+ component.triggerShowHideItem(defaultItem);
+
+ expect(showHideItemSpy.emit).toHaveBeenCalledTimes(1);
+ expect(showHideItemSpy.emit).toHaveBeenCalledWith(defaultItemVisibility);
+ });
+ });
+});
diff --git a/packages/stark-ui/src/modules/minimap/components/minimap.component.ts b/packages/stark-ui/src/modules/minimap/components/minimap.component.ts
new file mode 100644
index 0000000000..fb4eb68c97
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/components/minimap.component.ts
@@ -0,0 +1,163 @@
+import { STARK_LOGGING_SERVICE, StarkLoggingService } from "@nationalbankbelgium/stark-core";
+import {
+ ApplicationRef,
+ Component,
+ ElementRef,
+ EventEmitter,
+ Inject,
+ Input,
+ OnDestroy,
+ OnInit,
+ Output,
+ Renderer2,
+ ViewEncapsulation
+} from "@angular/core";
+import { ItemVisibility, StarkDOMUtil, StarkMinimapItemProperties } from "@nationalbankbelgium/stark-ui";
+import { AbstractStarkUiComponent } from "../../../common/classes/abstract-component";
+
+export type StarkMinimapComponentMode = "compact";
+
+/**
+ * Name of the component
+ */
+const componentName: string = "stark-minimap";
+
+/**
+ * Component to display a minimap which permits to toggle the visibility of passed elements.
+ * The minimap shows the label of the elements to display with a checkbox to enable/disable the visibility
+ */
+@Component({
+ selector: "stark-minimap",
+ templateUrl: "./minimap.component.html",
+ encapsulation: ViewEncapsulation.None,
+ host: {
+ class: componentName
+ }
+})
+export class StarkMinimapComponent extends AbstractStarkUiComponent implements OnInit, OnDestroy {
+ /**
+ * Array of StarkMinimapItemProperties objects which define the items to display in the minimap.
+ */
+ @Input()
+ public items: StarkMinimapItemProperties[];
+
+ /**
+ * Array of names of the items that are visible.
+ */
+ @Input()
+ public visibleItems: string[];
+
+ /**
+ * the minimap mode we want to display
+ */
+ @Input()
+ public mode?: StarkMinimapComponentMode;
+
+ /**
+ * Output that will emit the selected element to be shown/hidden
+ */
+ @Output()
+ public showHideItem: EventEmitter = new EventEmitter();
+
+ public windowClickHandler: EventListener;
+ public isDisplayedMenu: boolean;
+
+ public constructor(
+ @Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService,
+ protected renderer: Renderer2,
+ protected elementRef: ElementRef,
+ protected applicationRef: ApplicationRef
+ ) {
+ super(renderer, elementRef);
+ }
+
+ public ngOnInit(): void {
+ super.ngOnInit();
+ this.isDisplayedMenu = false;
+ this.attachWindowClickHandler();
+ }
+
+ /**
+ * Component lifecycle hook
+ */
+ public ngOnDestroy(): void {
+ this.logger.debug(componentName + ": removing clickHandler");
+ this.removeWindowClickHandler();
+ }
+
+ /**
+ * Retrieve the label of an item
+ * @param itemToHandle - the item whose label we want to retrieve
+ * @returns the label of the item
+ */
+ public getItemLabel(itemToHandle: StarkMinimapItemProperties): string {
+ if (itemToHandle.label) {
+ return itemToHandle.label;
+ }
+
+ return itemToHandle.name;
+ }
+
+ /**
+ * Attach a handler when a click is performed on the window
+ */
+ public attachWindowClickHandler(): void {
+ this.windowClickHandler = (event: Event) => {
+ if (this.isDisplayedMenu) {
+ const parentElement: Element | undefined = StarkDOMUtil.searchParentElementByClass(
+ event.target,
+ "stark-minimap-dropdown-toggle"
+ );
+
+ if (!parentElement) {
+ this.toggleDropdownMenu();
+ this.applicationRef.tick();
+ }
+ }
+ };
+
+ window.addEventListener("click", this.windowClickHandler);
+ }
+
+ /**
+ * remove the handler attached to a window
+ */
+ public removeWindowClickHandler(): void {
+ window.removeEventListener("click", this.windowClickHandler);
+ }
+
+ /**
+ * Return true/false if the given item is already visible or if the priority (if specified) for such item is not "hidden"
+ * Otherwise, the item is considered to be hidden by default
+ */
+ public isItemVisible(itemToHandle: StarkMinimapItemProperties): boolean {
+ return this.visibleItems instanceof Array ? this.visibleItems.indexOf(itemToHandle.name) > -1 : false;
+ }
+
+ /**
+ * Display / Hide the dropdown menu
+ */
+ public toggleDropdownMenu(): void {
+ this.isDisplayedMenu = !this.isDisplayedMenu;
+ }
+
+ /**
+ * triggers the show/hide event on an item
+ * @param itemToHandle : item - the item to show/hide
+ */
+ public triggerShowHideItem(itemToHandle: StarkMinimapItemProperties): void {
+ const visibleItem: ItemVisibility = {
+ isVisible: !this.isItemVisible(itemToHandle),
+ item: itemToHandle
+ };
+ this.showHideItem.emit(visibleItem);
+ }
+
+ /**
+ * @ignore
+ */
+ public trackItemFn(_itemToHandle: any): string {
+ // FIXME: cannot call areSimpleTypes() from the component since this track function gets no context
+ return _itemToHandle;
+ }
+}
diff --git a/packages/stark-ui/src/modules/minimap/minimap.module.ts b/packages/stark-ui/src/modules/minimap/minimap.module.ts
new file mode 100644
index 0000000000..9194e26366
--- /dev/null
+++ b/packages/stark-ui/src/modules/minimap/minimap.module.ts
@@ -0,0 +1,16 @@
+import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { StarkMinimapComponent } from "./components/minimap.component";
+import { MatButtonModule } from "@angular/material/button";
+import { MatCheckboxModule } from "@angular/material/checkbox";
+import { MatIconModule } from "@angular/material/icon";
+import { MatTooltipModule } from "@angular/material/tooltip";
+import { CommonModule } from "@angular/common";
+import { TranslateModule } from "@ngx-translate/core";
+
+@NgModule({
+ declarations: [StarkMinimapComponent],
+ imports: [CommonModule, FormsModule, MatButtonModule, MatCheckboxModule, MatIconModule, MatTooltipModule, TranslateModule],
+ exports: [StarkMinimapComponent]
+})
+export class StarkMinimapModule {}
diff --git a/showcase/src/app/app.component.ts b/showcase/src/app/app.component.ts
index 5f429c4dac..5eb3fab4cb 100644
--- a/showcase/src/app/app.component.ts
+++ b/showcase/src/app/app.component.ts
@@ -147,6 +147,13 @@ export class AppComponent implements OnInit {
isEnabled: true,
targetState: "demo.language-selector"
},
+ {
+ id: "menu-stark-ui-components-minimap",
+ label: "Minimap",
+ isVisible: true,
+ isEnabled: true,
+ targetState: "demo.minimap"
+ },
{
id: "menu-stark-ui-components-pagination",
label: "Pagination",
diff --git a/showcase/src/app/app.module.ts b/showcase/src/app/app.module.ts
index 8df1587d54..6179692525 100644
--- a/showcase/src/app/app.module.ts
+++ b/showcase/src/app/app.module.ts
@@ -57,6 +57,7 @@ import {
StarkAppMenuModule,
StarkAppSidebarModule,
StarkDatePickerModule,
+ StarkMinimapModule,
StarkLanguageSelectorModule,
StarkSessionUiModule,
StarkSvgViewBoxModule,
@@ -228,6 +229,7 @@ export const metaReducers: MetaReducer[] = ENV !== "production" ? [logger
StarkLanguageSelectorModule,
StarkSvgViewBoxModule,
StarkDatePickerModule,
+ StarkMinimapModule,
StarkToastNotificationModule.forRoot({
delay: 5000,
position: "top right",
diff --git a/showcase/src/app/demo/demo.module.ts b/showcase/src/app/demo/demo.module.ts
index 1d5528af4d..08141e85e4 100644
--- a/showcase/src/app/demo/demo.module.ts
+++ b/showcase/src/app/demo/demo.module.ts
@@ -29,6 +29,7 @@ import {
StarkAppMenuModule,
StarkPaginationModule,
StarkPrettyPrintModule,
+ StarkMinimapModule,
StarkSliderModule,
StarkSvgViewBoxModule,
StarkTableModule
@@ -49,6 +50,7 @@ import { DemoKeyboardDirectivesComponent } from "./keyboard-directives/demo-keyb
import { DemoLanguageSelectorComponent } from "./language-selector/demo-language-selector.component";
import { DemoLogoutComponent } from "./logout/demo-logout.component";
import { DemoMenuComponent } from "./menu/demo-menu.component";
+import { DemoMinimapComponent } from "./minimap/demo-minimap.component";
import { DemoPaginationComponent } from "./pagination/demo-pagination.component";
import { DemoPrettyPrintComponent } from "./pretty-print/demo-pretty-print.component";
import { DemoSidebarComponent } from "./sidebar/demo-sidebar.component";
@@ -88,6 +90,7 @@ import { DEMO_STATES } from "./routes";
StarkDateRangePickerModule,
StarkDropdownModule,
StarkKeyboardDirectivesModule,
+ StarkMinimapModule,
StarkLanguageSelectorModule,
StarkPaginationModule,
StarkPrettyPrintModule,
@@ -112,6 +115,7 @@ import { DEMO_STATES } from "./routes";
DemoLanguageSelectorComponent,
DemoLogoutComponent,
DemoMenuComponent,
+ DemoMinimapComponent,
DemoPaginationComponent,
DemoPrettyPrintComponent,
DemoSidebarComponent,
@@ -136,6 +140,7 @@ import { DEMO_STATES } from "./routes";
DemoKeyboardDirectivesComponent,
DemoLanguageSelectorComponent,
DemoLogoutComponent,
+ DemoMinimapComponent,
DemoMenuComponent,
DemoPaginationComponent,
DemoPrettyPrintComponent,
diff --git a/showcase/src/app/demo/index.ts b/showcase/src/app/demo/index.ts
index 8d455f5055..627c007fa1 100644
--- a/showcase/src/app/demo/index.ts
+++ b/showcase/src/app/demo/index.ts
@@ -13,6 +13,7 @@ export * from "./header";
export * from "./keyboard-directives";
export * from "./language-selector";
export * from "./logout";
+export * from "./minimap";
export * from "./menu";
export * from "./pagination";
export * from "./pretty-print";
diff --git a/showcase/src/app/demo/minimap/demo-minimap.component.html b/showcase/src/app/demo/minimap/demo-minimap.component.html
new file mode 100644
index 0000000000..0aed30d85b
--- /dev/null
+++ b/showcase/src/app/demo/minimap/demo-minimap.component.html
@@ -0,0 +1,18 @@
+SHOWCASE.DEMO.MINIMAP.TITLE
+
+
+
+
+
diff --git a/showcase/src/app/demo/minimap/demo-minimap.component.scss b/showcase/src/app/demo/minimap/demo-minimap.component.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/showcase/src/app/demo/minimap/demo-minimap.component.ts b/showcase/src/app/demo/minimap/demo-minimap.component.ts
new file mode 100644
index 0000000000..78ac811e9b
--- /dev/null
+++ b/showcase/src/app/demo/minimap/demo-minimap.component.ts
@@ -0,0 +1,52 @@
+import { Component, Inject, OnInit } from "@angular/core";
+import { STARK_LOGGING_SERVICE, StarkLoggingService } from "@nationalbankbelgium/stark-core";
+import { ReferenceLink } from "../../shared/reference-block";
+import { ItemVisibility, StarkMinimapItemProperties } from "@nationalbankbelgium/stark-ui";
+
+@Component({
+ selector: "demo-minimap",
+ templateUrl: "./demo-minimap.component.html",
+ styleUrls: ["./demo-minimap.component.scss"]
+})
+export class DemoMinimapComponent implements OnInit {
+ public items: StarkMinimapItemProperties[];
+ public visibleItems: string[];
+ public referenceList: ReferenceLink[];
+
+ public constructor(@Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService) {}
+
+ /**
+ * Component lifecycle hook
+ */
+ public ngOnInit(): void {
+ this.items = [
+ { name: "First", label: "First" },
+ { name: "Second", label: "Second" },
+ { name: "Third", label: "Third" },
+ { name: "Fourth", label: "Fourth" }
+ ];
+
+ this.visibleItems = [this.items[0].name, this.items[1].name, this.items[2].name, this.items[3].name];
+
+ this.referenceList = [
+ {
+ label: "Stark Minimap component",
+ url: "https://stark.nbb.be/api-docs/stark-ui/latest/components/StarkMinimapComponent.html"
+ }
+ ];
+ }
+
+ public showHideItem(itemToHandle: ItemVisibility): void {
+ const index: number = this.visibleItems.indexOf(itemToHandle.item.name);
+
+ if (index !== -1) {
+ if (!itemToHandle.isVisible) {
+ this.visibleItems = [...this.visibleItems.slice(0, index), ...this.visibleItems.slice(index + 1)];
+ }
+ } else {
+ if (itemToHandle.isVisible) {
+ this.visibleItems = [...this.visibleItems, itemToHandle.item.name];
+ }
+ }
+ }
+}
diff --git a/showcase/src/app/demo/minimap/index.ts b/showcase/src/app/demo/minimap/index.ts
new file mode 100644
index 0000000000..610cc3f921
--- /dev/null
+++ b/showcase/src/app/demo/minimap/index.ts
@@ -0,0 +1 @@
+export * from "./demo-minimap.component";
diff --git a/showcase/src/app/demo/routes.ts b/showcase/src/app/demo/routes.ts
index 085cc8e3b1..4d6dbddd37 100644
--- a/showcase/src/app/demo/routes.ts
+++ b/showcase/src/app/demo/routes.ts
@@ -22,6 +22,7 @@ import { DemoSidebarComponent } from "./sidebar";
import { DemoTableComponent } from "./table";
import { DemoToastComponent } from "./toast";
import { DemoTypographyComponent } from "./typography";
+import { DemoMinimapComponent } from "./minimap";
export const DEMO_STATES: Ng2StateDeclaration[] = [
{ name: "demo", url: "^/demo", abstract: true, parent: "app" },
@@ -105,6 +106,11 @@ export const DEMO_STATES: Ng2StateDeclaration[] = [
url: "/menu",
views: { "@": { component: DemoMenuComponent } }
},
+ {
+ name: "demo.minimap",
+ url: "/minimap",
+ views: { "@": { component: DemoMinimapComponent } }
+ },
{
name: "demo.pagination",
url: "/pagination",
diff --git a/showcase/src/assets/examples/minimap/compact.html b/showcase/src/assets/examples/minimap/compact.html
new file mode 100644
index 0000000000..600d5eb153
--- /dev/null
+++ b/showcase/src/assets/examples/minimap/compact.html
@@ -0,0 +1,2 @@
+
+
diff --git a/showcase/src/assets/examples/minimap/compact.ts b/showcase/src/assets/examples/minimap/compact.ts
new file mode 100644
index 0000000000..af4089b14b
--- /dev/null
+++ b/showcase/src/assets/examples/minimap/compact.ts
@@ -0,0 +1,47 @@
+import { Component, OnInit } from "@angular/core";
+import { ItemVisibility, StarkMinimapItemProperties } from "@nationalbankbelgium/stark-ui";
+
+@Component({
+ selector: "demo-minimap",
+ templateUrl: "./compact.html"
+})
+export class DemoCompactMinimapComponent implements OnInit {
+ public items: StarkMinimapItemProperties[];
+ public visibleItems: string[];
+
+ public constructor() {
+ //
+ }
+
+ /**
+ * Component lifecycle hook
+ */
+ public ngOnInit(): void {
+ this.items = [
+ { name: "first", label: "first" },
+ { name: "second", label: "second" },
+ { name: "third", label: "third" },
+ { name: "fourth", label: "fourth" }
+ ];
+
+ this.visibleItems = [this.items[0].name, this.items[1].name, this.items[2].name, this.items[3].name];
+ }
+
+ /**
+ * This method is used here to retrieve from the list of visible items the items that should be hidden.
+ * @param itemToHandle - the item to analyse
+ */
+ public showHideItem(itemToHandle: ItemVisibility): void {
+ const index: number = this.visibleItems.indexOf(itemToHandle.item.name);
+
+ if (index !== -1) {
+ if (!itemToHandle.isVisible) {
+ this.visibleItems = [...this.visibleItems.slice(0, index), ...this.visibleItems.slice(index + 1)];
+ }
+ } else {
+ if (itemToHandle.isVisible) {
+ this.visibleItems = [...this.visibleItems, itemToHandle.item.name];
+ }
+ }
+ }
+}
diff --git a/showcase/src/assets/examples/minimap/full.html b/showcase/src/assets/examples/minimap/full.html
new file mode 100644
index 0000000000..30ec2c8e6e
--- /dev/null
+++ b/showcase/src/assets/examples/minimap/full.html
@@ -0,0 +1,2 @@
+
+
diff --git a/showcase/src/assets/examples/minimap/full.ts b/showcase/src/assets/examples/minimap/full.ts
new file mode 100644
index 0000000000..faa8ae91b1
--- /dev/null
+++ b/showcase/src/assets/examples/minimap/full.ts
@@ -0,0 +1,43 @@
+import { Component, OnInit } from "@angular/core";
+import { ItemVisibility, StarkMinimapItemProperties } from "@nationalbankbelgium/stark-ui";
+
+@Component({
+ selector: "demo-minimap",
+ templateUrl: "./full.html"
+})
+export class DemoFullMinimapComponent implements OnInit {
+ public items: StarkMinimapItemProperties[];
+ public visibleItems: string[];
+
+ public constructor() {
+ //
+ }
+
+ /**
+ * Component lifecycle hook
+ */
+ public ngOnInit(): void {
+ this.items = [
+ { name: "first", label: "first" },
+ { name: "second", label: "second" },
+ { name: "third", label: "third" },
+ { name: "fourth", label: "fourth" }
+ ];
+
+ this.visibleItems = [this.items[0].name, this.items[1].name, this.items[2].name, this.items[3].name];
+ }
+
+ public showHideItem(itemToHandle: ItemVisibility): void {
+ const index: number = this.visibleItems.indexOf(itemToHandle.item.name);
+
+ if (index !== -1) {
+ if (!itemToHandle.isVisible) {
+ this.visibleItems = [...this.visibleItems.slice(0, index), ...this.visibleItems.slice(index + 1)];
+ }
+ } else {
+ if (itemToHandle.isVisible) {
+ this.visibleItems = [...this.visibleItems, itemToHandle.item.name];
+ }
+ }
+ }
+}
diff --git a/showcase/src/assets/translations/en.json b/showcase/src/assets/translations/en.json
index badb25ad52..3c1e1eab6f 100644
--- a/showcase/src/assets/translations/en.json
+++ b/showcase/src/assets/translations/en.json
@@ -154,6 +154,11 @@
"SECTIONS": "Menu with sections",
"TITLE": "Stark app menu"
},
+ "MINIMAP": {
+ "TITLE": "Stark Minimap",
+ "FULL": "Minimap (classic version)",
+ "COMPACT": "Minimap (compact version)"
+ },
"PAGINATION": {
"ADVANCED_CONFIGURATION": "Pagination with advanced configuration",
"COMPACT_CONFIGURATION": "Pagination in compact mode",
diff --git a/showcase/src/assets/translations/fr.json b/showcase/src/assets/translations/fr.json
index 5314b52b58..3b9e6ee61b 100644
--- a/showcase/src/assets/translations/fr.json
+++ b/showcase/src/assets/translations/fr.json
@@ -154,6 +154,11 @@
"SECTIONS": "Menu avec sections",
"TITLE": "Stark app menu"
},
+ "MINIMAP": {
+ "TITLE": "Stark Minimap",
+ "FULL": "Minimap (version classic)",
+ "COMPACT": "Minimap (version compacte)"
+ },
"PAGINATION": {
"ADVANCED_CONFIGURATION": "Pagination avec configuration avancée",
"COMPACT_CONFIGURATION": "Pagination en mode compact",
diff --git a/showcase/src/assets/translations/nl.json b/showcase/src/assets/translations/nl.json
index 1a83eeb160..324af8f6d5 100644
--- a/showcase/src/assets/translations/nl.json
+++ b/showcase/src/assets/translations/nl.json
@@ -149,6 +149,11 @@
"LOGOUT_CUSTOM_ICON": "Logout-knop - Aangepast pictogram",
"TITLE": "Stark app logout"
},
+ "MINIMAP": {
+ "TITLE": "Stark Minimap",
+ "FULL": "Minimap (klassieke versie)",
+ "COMPACT": "Minimap (compacte version)"
+ },
"MENU": {
"SIMPLE": "Simple menu",
"SECTIONS": "Menu with sections",
diff --git a/showcase/src/styles/_stark-styles.scss b/showcase/src/styles/_stark-styles.scss
index a95594de37..3b18521a11 100644
--- a/showcase/src/styles/_stark-styles.scss
+++ b/showcase/src/styles/_stark-styles.scss
@@ -20,6 +20,8 @@ IMPORTANT: Stark styles are provided as SCSS styles so they should be imported i
@import "~@nationalbankbelgium/stark-ui/src/modules/collapsible/components/collapsible.component";
@import "~@nationalbankbelgium/stark-ui/src/modules/date-range-picker/components/date-range-picker.component";
@import "~@nationalbankbelgium/stark-ui/src/modules/language-selector/components/language-selector.component";
+@import "~@nationalbankbelgium/stark-ui/src/modules/minimap/components/minimap.component";
+@import "~@nationalbankbelgium/stark-ui/src/modules/minimap/components/minimap-theme";
@import "~@nationalbankbelgium/stark-ui/src/modules/slider/components/slider-theme";
@import "~@nationalbankbelgium/stark-ui/src/modules/pagination/components/pagination.component";
@import "~@nationalbankbelgium/stark-ui/src/modules/pagination/components/pagination-theme";