Skip to content
This repository was archived by the owner on Mar 8, 2024. It is now read-only.

Shared component dropdown #10

Merged
merged 34 commits into from
Aug 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4e8d7f3
Kern dropdowns refactor
lumburovskalina Jul 25, 2022
2df4c4f
Add checkboxes option to kern dropdown
lumburovskalina Jul 25, 2022
2d9c6eb
Remove unused code
lumburovskalina Jul 25, 2022
aaa370d
Removed unused code
lumburovskalina Jul 25, 2022
ff23ade
Kern dropdown improvements for disabled buttons
lumburovskalina Jul 26, 2022
89fe4e3
Removed unused code
lumburovskalina Jul 26, 2022
379df82
Remove commented code
lumburovskalina Jul 26, 2022
a2f284a
Adds first (unfinished) version of iteration
Aug 1, 2022
2b6ad4c
With icon option
Aug 2, 2022
361714f
Adds checkbox logic
Aug 2, 2022
c788e7d
Merge pull request #17 from code-kern-ai/shared-component-dropdown-it
JWittmeyer Aug 2, 2022
1ce7cf5
Replaced dropdown with one component
lumburovskalina Aug 8, 2022
354bfd3
Removed unused code
lumburovskalina Aug 8, 2022
ab2699d
Removed unused code
lumburovskalina Aug 8, 2022
548f550
Renamed existing component to kern dropdown
lumburovskalina Aug 8, 2022
d0020d0
Reverted change
lumburovskalina Aug 8, 2022
7f167cf
Removed dummy code
lumburovskalina Aug 8, 2022
9427463
Merge
lumburovskalina Aug 8, 2022
bed0254
Removed commented code
lumburovskalina Aug 8, 2022
5a3e4d3
Header zindex over sticky header on heuristics and lookup lists
lumburovskalina Aug 8, 2022
b252bcf
Console log removed
lumburovskalina Aug 8, 2022
cf5ba16
Improvements on dropdown shared component
lumburovskalina Aug 8, 2022
86bb025
Prefilled heuristics
lumburovskalina Aug 9, 2022
37182a2
Merge branch 'dev' into shared-component-dropdown
JWittmeyer Aug 9, 2022
c7a9403
resolve merge conflicts
Aug 10, 2022
d60c7e2
Updated dropdown options
lumburovskalina Aug 10, 2022
8521ec8
More flexible dropdown
lumburovskalina Aug 10, 2022
42b7056
Updated helped with more explanations
lumburovskalina Aug 10, 2022
1e8f0ac
Adds differnt logic for color generation
Aug 10, 2022
d017c46
Remove debug values
Aug 10, 2022
ea398d5
Width changes
lumburovskalina Aug 10, 2022
d026c4a
Merge branch 'shared-component-dropdown' of github.com:code-kern-ai/r…
lumburovskalina Aug 10, 2022
8926349
Small fixes on dropdown
lumburovskalina Aug 11, 2022
5d316f0
Function name changed
lumburovskalina Aug 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ testem.log
# System Files
.DS_Store
Thumbs.db

.angular/
3 changes: 3 additions & 0 deletions src/app/base/base.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { SidebarPmComponent } from './components/sidebar-pm/sidebar-pm.component
import { DropdownDirective } from './directives/dropdown.directive';
import { PercentRoundPipe } from './pipes/decimal-round.pipe';
import { HeaderComponent } from './components/header/header.component';
import { DropdownComponent } from './components/dropdown/dropdown.component';
import { HeuristicStatusesComponent } from './components/heuristic-statuses/heuristic-statuses.component';

@NgModule({
Expand All @@ -28,6 +29,7 @@ import { HeuristicStatusesComponent } from './components/heuristic-statuses/heur
DropdownDirective,
PercentRoundPipe,
HeaderComponent,
DropdownComponent,
HeuristicStatusesComponent
],
imports: [CommonModule, AppRoutingModule, HighlightModule],
Expand All @@ -50,6 +52,7 @@ import { HeuristicStatusesComponent } from './components/heuristic-statuses/heur
DropdownDirective,
PercentRoundPipe,
HeaderComponent,
DropdownComponent,
HeuristicStatusesComponent
],
providers: [
Expand Down
50 changes: 50 additions & 0 deletions src/app/base/components/dropdown/dropdown-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { FormArray } from "@angular/forms";

/**
* Optionset for kern dropdown
* @optionArray {string[] | FormArray[] | any[]} - Can be any array. string array is just used, FormArray or any object array tries to use "name" property then "text" last first string property
* @buttonCaption {string, optional} - used as caption for the button, if not given the first / current value is used
* @valuePropertyPath {string, optional} - if undefined option text is returned, else (e.g. name.tmp.xyz) the path is split and used to access the object property
* @keepDropdownOpen {boolean, optional} - stops the event propagation of the click event and therfore keeps the menu open
* @buttonTooltip {string, optional} - adds a tooltip if defined
* @isDisabled {boolean, optional} - disables the dropdown
* @isOptionDisabled {boolean[], optional} - disables the dropdown option (needs to be the exact same length as the optionArray)
* @optionIcons {string[], optional} - displays a predfined icon if set for the index (needs to be the exact same length as the optionArray)
* @hasCheckboxes {boolean, optional} - helper for checkbox like dropdowns (e.g. data browser)
* @buttonVersion {string, optional} - defaults to 'default' (button with a caption text), '...', 'userIcon'
* @avatarUri {string, optional} - link to the avatar image for logged user
* @prefix {string, optional} - prefix to the main name in the option
* @postfix {string, optional} - postfix to the main name in the option
* @buttonBgColor {string, optional} - background color for the button
* @buttonTextColor {string, optional} - text color for the button
* @optionDescriptions {string, optional} - array with optional descriptions to the options
* @hoverColor {string, optional} - background color on hover for the dropdown options
* @textColor {string, optional} - text color for the dropdown options
* @textHoverColor {string, optional} - text color on hover for the dropdown options
* @textSize {string, optional} - text size for the dropdown options
* @isButtonSampleProjects {boolean, optional} - checks if the button is the specific one for sample project
*/
export type DropdownOptions = {
optionArray: string[] | FormArray[] | any[];
buttonCaption?: string;
valuePropertyPath?: string;
keepDropdownOpen?: boolean;
buttonTooltip?: string;
isDisabled?: boolean;
isOptionDisabled?: boolean[];
optionIcons?: string[];
hasCheckboxes?: boolean;
buttonVersion?: string;
avatarUri?: string;
prefix?: string;
postfix?: string;
buttonBgColor?: string;
buttonTextColor?: string;
optionDescriptions?: string[];
hoverColor?: string;
textColor?: string;
textHoverColor?: string;
textSize?: string;
isButtonSampleProjects?: boolean;
};

196 changes: 196 additions & 0 deletions src/app/base/components/dropdown/dropdown.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
<div class="relative" [ngClass]="dropdownOptions.buttonVersion == 'default' ? ' w-max' : '' ">
<button #dropdownOpenButton type="button" [attr.data-tip]="dropdownOptions.buttonTooltip" *ngIf="dropdownOptions.buttonVersion == 'default'"
class="inline-flex rounded-md border shadow-sm px-4 items-center text-xs font-semibold cursor-pointer focus:ring-offset-2 focus:ring-offset-gray-400"
id="menu-button" aria-expanded="true" aria-haspopup="true" [disabled]="dropdownOptions.isDisabled"
[ngClass]="buttonClassList" (isMenuOpen)="toggleVisible($event, dropdownOptionsDiv)" appDropdown>
{{ dropdownOptions.hasCheckboxes?'':dropdownOptions.buttonCaption }}
<ng-template [ngIf]="dropdownOptions.hasCheckboxes">
<label class="truncate cursor-pointer">{{getDropdownDisplayText(dropdownOptions.optionArray,"EMPTY")}}
<span style="color:#2563eb">{{getDropdownDisplayText(dropdownOptions.optionArray,"NOT_NEGATED")}}</span>
<span style="color:#ef4444">{{getDropdownDisplayText(dropdownOptions.optionArray,"NEGATED")}}</span>
</label>
</ng-template>
<svg class="-mr-1 ml-auto h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<path fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd" />
</svg>
</button>

<svg *ngIf="dropdownOptions.buttonVersion== '...'" (isMenuOpen)="toggleVisible($event, dropdownOptionsDiv)" appDropdown
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 float-right cursor-pointer text-gray-500" viewBox="0 0 20 20"
fill="currentColor">
<path
d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
</svg>
<a *ngIf="dropdownOptions.buttonVersion== 'userIcon'" tabindex="0" class="w-full cursor-pointer">
<div data-intercom-target="User Avatar Button" (isMenuOpen)="toggleVisible($event, dropdownOptionsDiv)" appDropdown>
<img class="h-8 w-8" [src]="dropdownOptions.avatarUri">
</div>
</a>

<div #dropdownOptionsDiv
class="origin-top-right absolute mt-2 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none hidden"
[ngClass]="[dropdownClassList, dropdownOptions.isButtonSampleProjects ? 'width-sample-projects' : '', dropdownOptions.buttonVersion != '...' ? 'min-w-full': '']"
role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
<div class="py-1 cursor-pointer" role="none">
<div *ngFor="let caption of dropdownOptionCaptions;let i = index" (click)="performActionOnOption($event,i)"
[ngClass]="[dropdownOptions.textSize,dropdownOptions.textColor,dropdownOptions.optionDescriptions ? '' : 'flex' ,dropdownOptions.isOptionDisabled?.length && dropdownOptions.isOptionDisabled[i]?'opacity-50 cursor-not-allowed':'',!dropdownOptions.hasCheckboxes ? dropdownOptions.hoverColor + ' ' +dropdownOptions.textHoverColor:'']"
[ngStyle]="{'border-bottom': dropdownOptions.isButtonSampleProjects && i%2 == 0 && i!=dropdownOptionCaptions.length-1 ? '1px dashed #e2e8f0' : (dropdownOptions.isButtonSampleProjects && i%2 != 0 && i!=dropdownOptionCaptions.length-1 ? '1px solid #e2e8f0' : null) }"
class="block px-2 py-1.5 flex-row flex-nowrap items-center gap-x-2 w-max min-w-full"
role="menuitem" tabindex="-1" id="menu-item-0">
<ng-template [ngIf]="dropdownOptions.hasCheckboxes">
<div class="h-4 w-4 border-gray-300 border rounded hover:bg-gray-200"
[ngStyle]="{'background-color':getActiveNegateGroupColor(dropdownOptions.optionArray[i]), 'border-color':getActiveNegateGroupColor(dropdownOptions.optionArray[i])}">
</div>
</ng-template>
<ng-template [ngIf]="dropdownOptions.optionIcons?.length">
<ng-container [ngTemplateOutlet]="icons"
[ngTemplateOutletContext]="{iconName:dropdownOptions.optionIcons[i]}">
</ng-container>
</ng-template>
{{ caption }}

<p *ngIf="dropdownOptions.optionDescriptions && dropdownOptions.optionDescriptions[i] != ''" class="mt-2">
{{dropdownOptions.optionDescriptions[i]}}
</p>
</div>
</div>
</div>
</div>


<ng-template #icons let-iconName="iconName">
<ng-container [ngSwitch]="iconName">
<ng-template ngSwitchDefault>
</ng-template>
<ng-template ngSwitchCase="clickbait">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-fish-hook inline-block" width="20"
height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M16 9v6a5 5 0 0 1 -10 0v-4l3 3"></path>
<circle cx="16" cy="7" r="2"></circle>
<path d="M16 5v-2"></path>
</svg>
</ng-template>
<ng-template ngSwitchCase="conversational-ai">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-message-circle inline-block" width="20"
height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M3 20l1.3 -3.9a9 8 0 1 1 3.4 2.9l-4.7 1"></path>
<line x1="12" y1="12" x2="12" y2="12.01"></line>
<line x1="8" y1="12" x2="8" y2="12.01"></line>
<line x1="16" y1="12" x2="16" y2="12.01"></line>
</svg>
</ng-template>
<ng-template ngSwitchCase="ag-news">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-news inline-block" width="20" height="20"
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path
d="M16 6h3a1 1 0 0 1 1 1v11a2 2 0 0 1 -4 0v-13a1 1 0 0 0 -1 -1h-10a1 1 0 0 0 -1 1v12a3 3 0 0 0 3 3h11">
</path>
<line x1="8" y1="8" x2="12" y2="8"></line>
<line x1="8" y1="12" x2="12" y2="12"></line>
<line x1="8" y1="16" x2="12" y2="16"></line>
</svg>
</ng-template>
<ng-template ngSwitchCase="select-all">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-square-check inline-block"
width="20" height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<rect x="4" y="4" width="16" height="16" rx="2"></rect>
<path d="M9 12l2 2l4 -4"></path>
</svg>
</ng-template>
<ng-template ngSwitchCase="deselect-all">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-square inline-block" width="20"
height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<rect x="4" y="4" width="16" height="16" rx="2"></rect>
</svg>
</ng-template>
<ng-template ngSwitchCase="run">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block" viewBox="0 0 20 20"
fill="currentColor">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z"
clip-rule="evenodd" />
</svg>
</ng-template>
<ng-template ngSwitchCase="edit-term">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block" viewBox="0 0 20 20"
fill="currentColor">
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z" />
<path fill-rule="evenodd"
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
clip-rule="evenodd" />
</svg>
</ng-template>
<ng-template ngSwitchCase="remove-term">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block" viewBox="0 0 20 20"
fill="currentColor">
<path fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd" />
</svg>
</ng-template>
<ng-template ngSwitchCase="whitelist-term">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block" viewBox="0 0 20 20"
fill="currentColor">
<path fill-rule="evenodd"
d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2.001 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clip-rule="evenodd" />
</svg>
</ng-template>
<ng-template ngSwitchCase="blacklist-term">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block" viewBox="0 0 20 20"
fill="currentColor">
<path fill-rule="evenodd"
d="M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zM11 14a1 1 0 11-2 0 1 1 0 012 0zm0-7a1 1 0 10-2 0v3a1 1 0 102 0V7z"
clip-rule="evenodd" />
</svg>
</ng-template>
<ng-template ngSwitchCase="delete-selected">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block" fill="none"
viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
</ng-template>
<ng-template ngSwitchCase="labeling-function">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block"
viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd"
d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z"
clip-rule="evenodd" />
</svg>
</ng-template>

<ng-template ngSwitchCase="active-learning">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block"
viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd"
d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z"
clip-rule="evenodd" />
</svg>
</ng-template>

<ng-template ngSwitchCase="zero-shot">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block"
viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd"
d="M5 2a1 1 0 011 1v1h1a1 1 0 010 2H6v1a1 1 0 01-2 0V6H3a1 1 0 010-2h1V3a1 1 0 011-1zm0 10a1 1 0 011 1v1h1a1 1 0 110 2H6v1a1 1 0 11-2 0v-1H3a1 1 0 110-2h1v-1a1 1 0 011-1zM12 2a1 1 0 01.967.744L14.146 7.2 17.5 9.134a1 1 0 010 1.732l-3.354 1.935-1.18 4.455a1 1 0 01-1.933 0L9.854 12.8 6.5 10.866a1 1 0 010-1.732l3.354-1.935 1.18-4.455A1 1 0 0112 2z"
clip-rule="evenodd" />
</svg>
</ng-template>
</ng-container>

</ng-template>
11 changes: 11 additions & 0 deletions src/app/base/components/dropdown/dropdown.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.tooltip::before {
z-index: 50;
}

.width-icon-menues {
width: 128px;
}

.width-sample-projects {
width: 384px !important;
}
25 changes: 25 additions & 0 deletions src/app/base/components/dropdown/dropdown.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { DropdownComponent } from './dropdown.component';

describe('DropdownItComponent', () => {
let component: DropdownComponent;
let fixture: ComponentFixture<DropdownComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [DropdownComponent]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(DropdownComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading