From 0f3e996d686fbaa3c378baf1be576bd081f27ba5 Mon Sep 17 00:00:00 2001 From: Caleb Alldrin Date: Mon, 19 Feb 2024 14:47:42 -0800 Subject: [PATCH 1/6] Merge filter-sort --- package.json | 2 +- .../resource/resource.component.html | 7 +- .../resource/resource.component.spec.ts | 8 +- .../resources/resources.component.html | 134 ++++++++++++++++-- .../resources/resources.component.spec.ts | 4 + .../resources/resources.component.ts | 107 +++++++++++++- src/app/models/filters.ts | 5 + src/styles.css | 98 +++++++++---- yarn.lock | 2 +- 9 files changed, 321 insertions(+), 46 deletions(-) create mode 100644 src/app/models/filters.ts diff --git a/package.json b/package.json index d0d415c4..f002c899 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "angular2-uuid": "1.1.1", "components-font-awesome": "4.7.0", "core-js": "2.6.12", - "countries-list": "^3.0.5", + "countries-list": "3.0.5", "jsonapi-datastore": "0.4.0-beta", "lodash": "^4.17.21", "ng2-ace-editor": "0.3.9", diff --git a/src/app/components/resource/resource.component.html b/src/app/components/resource/resource.component.html index eb951410..26dabdb8 100644 --- a/src/app/components/resource/resource.component.html +++ b/src/app/components/resource/resource.component.html @@ -5,9 +5,12 @@ (click)="showDetails = !showDetails" > - {{ resource.name }} + {{ resource.name }} -
+
-
+
Instructions
    @@ -64,11 +67,126 @@
    Instructions

-
- +
+
+ { let comp: ResourcesComponent; @@ -48,6 +50,8 @@ describe('ResourcesComponent', () => { { provide: LanguageService, useValue: languageServiceStub }, { provide: NgbModal }, { provide: DraftService }, + { provide: ResourceTypeService }, + { provide: SystemService }, ], }).compileComponents(); })); diff --git a/src/app/components/resources/resources.component.ts b/src/app/components/resources/resources.component.ts index 62e53f64..1c6c4a7d 100644 --- a/src/app/components/resources/resources.component.ts +++ b/src/app/components/resources/resources.component.ts @@ -5,6 +5,11 @@ import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { CreateResourceComponent } from '../edit-resource/create-resource/create-resource.component'; import { Language } from '../../models/language'; import { LanguageService } from '../../service/language.service'; +import { ResourceType } from '../../../../src/app/models/resource-type'; +import { System } from '../../../../src/app/models/system'; +import { Filters } from '../../../../src/app/models/filters'; +import { SystemService } from '../../../../src/app/service/system.service'; +import { ResourceTypeService } from '../../../../src/app/service/resource-type.service'; @Component({ selector: 'admin-resources', @@ -13,36 +18,100 @@ import { LanguageService } from '../../service/language.service'; export class ResourcesComponent implements OnInit { resources: Resource[]; languages: Language[]; + resourceTypes: ResourceType[]; + systems: System[]; showInstructions = false; + showFilters = false; loadingResources = false; loadingLanguages = false; errorMessage: string; + filters: Filters; + totalFilters: number; + sortOrder: string; constructor( private resourceService: ResourceService, private languageService: LanguageService, private modalService: NgbModal, + protected systemService: SystemService, + protected resourceTypeService: ResourceTypeService, ) {} ngOnInit(): void { this.loadResources(); this.loadLanguages(); + this.loadFilters(); } - loadResources(): void { - this.loadingResources = true; + blankFilters(): Filters { + return { + type: [], + system: [], + other: [], + }; + } + loadResources(): void { this.resourceService .getResources( 'latest-drafts-translations,pages,custom-manifests,tips,attachments,variants', ) .then((resources) => { - this.resources = resources; + const localFilters = localStorage.getItem('filters'); + this.sortOrder = localStorage.getItem('sortOrder'); + this.filters = localFilters + ? JSON.parse(localFilters) + : this.blankFilters(); + this.totalFilters = Object.keys(this.filters).reduce( + (acc, item) => acc + this.filters[item].length, + 0, + ); + + this.resources = this.filters + ? resources.filter((r) => { + let visible = true; + if (this.filters['type'].length) { + if (!this.filters['type'].includes(r['resource-type'])) { + visible = false; + } + } + if (this.filters['system'].length) { + if (!this.filters['system'].includes(r['system']['id'])) { + visible = false; + } + } + if (this.filters['other'].length) { + if ( + !r['attr-hidden'] || + (r['attr-hidden'] && + !this.filters['other'].includes('hidden')) + ) { + visible = false; + } + } + return visible; + }) + : resources; + if (this.sortOrder === 'default') { + this.resources.sort( + (a, b) => + (a['attr-default-order'] || 100) - + (b['attr-default-order'] || 100), + ); + } }) .catch(this.handleError.bind(this)) .then(() => (this.loadingResources = false)); } + loadFilters(): void { + this.resourceTypeService.getResourceTypes().then((types) => { + this.resourceTypes = types; + }); + this.systemService.getSystems().then((systems) => { + this.systems = systems; + }); + } openCreateModal(): void { const modalRef: NgbModalRef = this.modalService.open( @@ -51,6 +120,38 @@ export class ResourcesComponent implements OnInit { modalRef.result.then(() => this.loadResources(), console.log); } + toggleResources = function ( + category: string, + optionId: string | number, + ): void { + const updatedFilters = + this.filters[category] && this.filters[category].includes(optionId) + ? { + ...this.filters, + [category]: this.filters[category].filter((e) => e !== optionId), + } + : this.filters[category] + ? { + ...this.filters, + [category]: [...this.filters[category], optionId], + } + : { + ...this.filters, + [category]: [optionId], + }; + localStorage.setItem('filters', JSON.stringify(updatedFilters)); + this.loadResources(); + }; + + clearFilters = function (): void { + localStorage.setItem('filters', JSON.stringify(this.blankFilters())); + this.loadResources(); + }; + updateSort = function (order: string): void { + localStorage.setItem('sortOrder', order); + this.loadResources(); + }; + trackByFunction(pIx: number, pItem: Resource) { if (!pItem || pIx < 0) { return null; diff --git a/src/app/models/filters.ts b/src/app/models/filters.ts new file mode 100644 index 00000000..048312da --- /dev/null +++ b/src/app/models/filters.ts @@ -0,0 +1,5 @@ +export class Filters { + type: string[] | null; + system: number[] | null; + other: string[] | null; +} diff --git a/src/styles.css b/src/styles.css index 5b8aea89..bb519679 100644 --- a/src/styles.css +++ b/src/styles.css @@ -21,44 +21,82 @@ /* Tooltip */ .tooltip { - display:inline-block; - position:relative; - border-bottom:1px dotted #666; - text-align:left; + display: inline-block; + position: relative; + border-bottom: 1px dotted #666; + text-align: left; } -.tooltip h3 {margin:12px 0;} +.tooltip h3 { + margin: 12px 0; +} .tooltip .tooltip-content { - min-width:200px; - max-width:400px; - top:-20px; - left:50%; - transform:translate(-30%,-100%); - padding:10px 20px; - color:#ffffff; - background-color:#009cdc; - font-weight:normal; - font-size:14px; - border-radius:8px; - position:absolute; - z-index:99999999; - box-sizing:border-box; - box-shadow:0 1px 8px rgba(0,0,0,0.5); - display:none; + min-width: 200px; + max-width: 400px; + top: -20px; + left: 50%; + transform: translate(-30%, -100%); + padding: 10px 20px; + color: #ffffff; + background-color: #009cdc; + font-weight: normal; + font-size: 14px; + border-radius: 8px; + position: absolute; + z-index: 99999999; + box-sizing: border-box; + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); + display: none; } .tooltip:hover .tooltip-content { - display:block; + display: block; } .tooltip .tooltip-content:after { - content:''; - position:absolute; - width:15px; - height:15px; - left:50%; - transform:translate(-50%,-50%) rotate(45deg); - background-color:#009cdc; - box-shadow:0 1px 8px rgba(0,0,0,0.5); + content: ''; + position: absolute; + width: 15px; + height: 15px; + left: 50%; + transform: translate(-50%, -50%) rotate(45deg); + background-color: #009cdc; + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); +} +.filter-dropdown-button { + cursor: pointer; + display: block; + width: 100%; + padding: 0.25rem 1rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.filter-dropdown-button:hover { + background-color: #f8f9fa; +} +.dropdown-menu > span { + padding-left: 1rem; + font-size: 0.875rem; +} +.card-header span.h4 i.fa { + visibility: hidden; + font-size: 15px; + margin-left: 5px; +} +.card-header:hover span.h4 i.fa { + visibility: visible; +} +#filterBadge { + translate: 0 -50%; + top: 50%; + width: 15px; } diff --git a/yarn.lock b/yarn.lock index 97b88c58..9c4edb21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2176,7 +2176,7 @@ cosmiconfig@^5.0.0: js-yaml "^3.13.1" parse-json "^4.0.0" -countries-list@^3.0.5: +countries-list@3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/countries-list/-/countries-list-3.0.5.tgz#34f2b76dfef5c5f47b0c2e536c0e9b2fb10e16a9" integrity sha512-JwaAU/wpoUoZk+6WSaGJL1WDoNCJ2vrQCkHOg/t3qoYIPH6kZ+SGAX3YZukMsKXbX1xkxU34pJOE+xr55O+Sww== From 2fdb69a7f242c217f708eb7d07a1595453718817 Mon Sep 17 00:00:00 2001 From: Caleb Alldrin Date: Thu, 22 Feb 2024 18:04:29 -0800 Subject: [PATCH 2/6] Merge filter-sort --- package.json | 2 +- .../resource/resource.component.html | 5 +- .../resources/resources.component.html | 52 +++--- .../resources/resources.component.spec.ts | 164 ++++++++++++++++++ .../resources/resources.component.ts | 114 ++++++------ src/styles.css | 61 ++++++- tslint.json | 3 - 7 files changed, 310 insertions(+), 91 deletions(-) diff --git a/package.json b/package.json index f002c899..d6ab91ce 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "ng build", "build:stage": "ng build -c staging", "build:prod": "ng build -c production", - "test": "ng test", + "test": "ng test --browsers=ChromeHeadless", "test:codecov": "ng test --watch=false --browsers=ChromeHeadless --code-coverage", "lint": "ng lint", "lint:fix": "ng lint --fix", diff --git a/src/app/components/resource/resource.component.html b/src/app/components/resource/resource.component.html index 26dabdb8..aa037c15 100644 --- a/src/app/components/resource/resource.component.html +++ b/src/app/components/resource/resource.component.html @@ -1,7 +1,8 @@
diff --git a/src/app/components/resources/resources.component.html b/src/app/components/resources/resources.component.html index 8e3d7189..b35d390c 100644 --- a/src/app/components/resources/resources.component.html +++ b/src/app/components/resources/resources.component.html @@ -1,9 +1,9 @@
- Translations + Tools
-
-
+
+
Instructions
  • @@ -70,12 +70,18 @@
    Instructions
-