From cebd6a21fd7f181eecf4e56f925841fddb6cfbe0 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 27 Jan 2023 09:21:22 -0600 Subject: [PATCH 001/150] adding script and new fields in table, also adding enum for collection status --- .../edu/wgu/osmt/collection/CollectionTable.kt | 12 +++++++++--- .../main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt | 10 ++++++++++ .../V2023.01.26__add_status_and_owner_fields.sql | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt create mode 100644 api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt index 48fcaa0a1..b91174fa8 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt @@ -1,12 +1,18 @@ package edu.wgu.osmt.collection +import edu.wgu.osmt.db.CollectionStatus import edu.wgu.osmt.db.PublishStatusUpdate import edu.wgu.osmt.db.TableWithUpdate import edu.wgu.osmt.keyword.KeywordTable import edu.wgu.osmt.richskill.RichSkillDescriptorTable import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.LongIdTable -import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.Column +import org.jetbrains.exposed.sql.ReferenceOption +import org.jetbrains.exposed.sql.Table +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.insertIgnore import org.jetbrains.exposed.sql.`java-time`.datetime import java.time.LocalDateTime @@ -23,8 +29,8 @@ object CollectionTable: TableWithUpdate, PublishStatusUp onDelete = ReferenceOption.RESTRICT, onUpdate = ReferenceOption.CASCADE ).nullable() - - + val owner = varchar("owner", 64) + val status = enumeration("status", CollectionStatus::class) } object CollectionSkills : Table("CollectionSkills") { diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt b/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt new file mode 100644 index 000000000..5b3e7fac6 --- /dev/null +++ b/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt @@ -0,0 +1,10 @@ +package edu.wgu.osmt.db + +const val WORKSPACE = "workspace" + +enum class CollectionStatus(val apiValue: String) { + Published(PUBLISHED), + Archived(ARCHIVED), + Draft(DRAFT), + Workspace(WORKSPACE); +} diff --git a/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql b/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql new file mode 100644 index 000000000..c19b7f456 --- /dev/null +++ b/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql @@ -0,0 +1,2 @@ +ALTER TABLE Collection ADD owner VARCHAR(64) NOT NULL; +ALTER TABLE Collection ADD status INT NOT NULL; \ No newline at end of file From 7cdf54088d379e71db0fd6e1037a8e2123167d7d Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 27 Jan 2023 11:59:08 -0600 Subject: [PATCH 002/150] correcting enum status type and script, also renaming owner field to be workspaceOwner --- .../edu/wgu/osmt/collection/CollectionTable.kt | 8 +++++--- .../kotlin/edu/wgu/osmt/db/CollectionStatus.kt | 10 ---------- .../edu/wgu/osmt/db/CollectionStatusEnum.kt | 16 ++++++++++++++++ .../V2023.01.26__add_status_and_owner_fields.sql | 5 +++-- 4 files changed, 24 insertions(+), 15 deletions(-) delete mode 100644 api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt create mode 100644 api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt index b91174fa8..cce555974 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt @@ -1,6 +1,6 @@ package edu.wgu.osmt.collection -import edu.wgu.osmt.db.CollectionStatus +import edu.wgu.osmt.db.CollectionStatusEnum import edu.wgu.osmt.db.PublishStatusUpdate import edu.wgu.osmt.db.TableWithUpdate import edu.wgu.osmt.keyword.KeywordTable @@ -29,8 +29,10 @@ object CollectionTable: TableWithUpdate, PublishStatusUp onDelete = ReferenceOption.RESTRICT, onUpdate = ReferenceOption.CASCADE ).nullable() - val owner = varchar("owner", 64) - val status = enumeration("status", CollectionStatus::class) + val workspaceOwner = varchar("workspace_owner", 64).index() + val status = customEnumeration( + "status", + fromDb = { value -> CollectionStatusEnum.valueOf(value as String) }, toDb = { it.name }) } object CollectionSkills : Table("CollectionSkills") { diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt b/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt deleted file mode 100644 index 5b3e7fac6..000000000 --- a/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatus.kt +++ /dev/null @@ -1,10 +0,0 @@ -package edu.wgu.osmt.db - -const val WORKSPACE = "workspace" - -enum class CollectionStatus(val apiValue: String) { - Published(PUBLISHED), - Archived(ARCHIVED), - Draft(DRAFT), - Workspace(WORKSPACE); -} diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt b/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt new file mode 100644 index 000000000..631aa4092 --- /dev/null +++ b/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt @@ -0,0 +1,16 @@ +package edu.wgu.osmt.db + +const val WORKSPACE = "workspace" + +enum class CollectionStatusEnum(val apiValue: String) { + Published(PUBLISHED), + Archived(ARCHIVED), + Draft(DRAFT), + Workspace(WORKSPACE); + + open val displayName: String = this.name + + companion object { + fun forApiValue(apiValue: String) = CollectionStatusEnum.values().find { it.name.toLowerCase() == apiValue.toLowerCase() } + } +} diff --git a/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql b/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql index c19b7f456..8b299b763 100644 --- a/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql +++ b/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql @@ -1,2 +1,3 @@ -ALTER TABLE Collection ADD owner VARCHAR(64) NOT NULL; -ALTER TABLE Collection ADD status INT NOT NULL; \ No newline at end of file +ALTER TABLE Collection ADD workspace_owner VARCHAR(64) NOT NULL; +ALTER TABLE Collection ADD status enum ('Draft','Published','Archived','Workspace') NOT NULL; +CREATE INDEX Collection_workspace_owner ON Collection (workspace_owner); \ No newline at end of file From 2c35fcd9322c39193c71d6495e314a79d215268a Mon Sep 17 00:00:00 2001 From: Edwin Santizo Date: Mon, 30 Jan 2023 15:19:02 -0700 Subject: [PATCH 003/150] Added the new db columns to the collection DAO and Doc --- .../main/kotlin/edu/wgu/osmt/collection/Collection.kt | 3 +++ .../kotlin/edu/wgu/osmt/collection/CollectionDao.kt | 6 ++++++ .../kotlin/edu/wgu/osmt/collection/CollectionDoc.kt | 11 ++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt index 834c7fa54..42f3d8c69 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt @@ -3,6 +3,7 @@ package edu.wgu.osmt.collection import edu.wgu.osmt.auditlog.Change import edu.wgu.osmt.auditlog.Comparison import edu.wgu.osmt.db.* +import edu.wgu.osmt.db.CollectionStatusEnum import edu.wgu.osmt.keyword.Keyword import edu.wgu.osmt.keyword.KeywordDao import edu.wgu.osmt.keyword.KeywordTypeEnum @@ -20,6 +21,8 @@ data class Collection( val uuid: String, val name: String, val author: Keyword? = null, + val workspaceOwner: String? = null, + val status: Enum, override val archiveDate: LocalDateTime? = null, override val publishDate: LocalDateTime? = null ) : DatabaseData, HasUpdateDate, PublishStatusDetails { diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt index 6013a0b7d..f6d7b2240 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt @@ -17,6 +17,8 @@ class CollectionDao(id: EntityID) : LongEntity(id), OutputsModel) : LongEntity(id), OutputsModel) : LongEntity(id), OutputsModel + ) From 63822082ea0a3f7edc7c7146e5b8e215439d258f Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:14:35 -0600 Subject: [PATCH 004/150] Add my workspace in header - Add my workspace button in header. - My workspace redirects to /my-workspace. - Change method skillsActive --- ui/src/app/navigation/header.component.html | 5 +++++ ui/src/app/navigation/header.component.ts | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/src/app/navigation/header.component.html b/ui/src/app/navigation/header.component.html index 7628dabfb..9ac81f756 100644 --- a/ui/src/app/navigation/header.component.html +++ b/ui/src/app/navigation/header.component.html @@ -26,6 +26,11 @@

Site Navigation

  • Collections
  • +
  • + + My Workspace + +
  • Icon Interactive diff --git a/ui/src/app/navigation/header.component.ts b/ui/src/app/navigation/header.component.ts index 425b31206..25f24dc31 100644 --- a/ui/src/app/navigation/header.component.ts +++ b/ui/src/app/navigation/header.component.ts @@ -38,8 +38,12 @@ export class HeaderComponent extends Whitelabelled implements OnInit { return window.location.pathname.startsWith("/collections") } + get myWorkspaceActive(): boolean { + return window.location.pathname.startsWith("/my-workspace") + } + get skillsActive(): boolean { - return !this.collectionsActive + return window.location.pathname.startsWith("/skills") } handleQuicklink(elementId: string): boolean { From 75d0396c3c4ad184d4d70c9a8aa14ecdcb4e83a6 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:17:02 -0600 Subject: [PATCH 005/150] Add my workspace component - Create my-workspace.component.ts. - Add my-workspace.component.ts to app.module.ts and app-routing.module.ts. --- ui/src/app/app-routing.module.ts | 7 +++- ui/src/app/app.module.ts | 4 ++- .../my-workspace/my-workspace.component.html | 1 + .../my-workspace.component.spec.ts | 25 +++++++++++++ .../my-workspace/my-workspace.component.ts | 35 +++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 ui/src/app/my-workspace/my-workspace.component.html create mode 100644 ui/src/app/my-workspace/my-workspace.component.spec.ts create mode 100644 ui/src/app/my-workspace/my-workspace.component.ts diff --git a/ui/src/app/app-routing.module.ts b/ui/src/app/app-routing.module.ts index 702db5057..d540b9b3d 100644 --- a/ui/src/app/app-routing.module.ts +++ b/ui/src/app/app-routing.module.ts @@ -21,6 +21,7 @@ import {PublishCollectionComponent} from "./collection/detail/publish-collection import {CollectionSkillSearchComponent} from "./collection/collection-skill-search.component" import {BatchImportComponent} from "./richskill/import/batch-import.component" import { ActionByRoles, ButtonAction } from "./auth/auth-roles" +import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" const routes: Routes = [ @@ -144,7 +145,11 @@ const routes: Routes = [ component: AdvancedSearchComponent, canActivate: [AuthGuard], }, - + { + path: "my-workspace", + component: MyWorkspaceComponent, + canActivate: [AuthGuard] + }, /* PUBLIC VIEWS */ {path: "skills/:uuid", component: RichSkillPublicComponent}, {path: "collections/:uuid", component: CollectionPublicComponent}, diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index f81052186..95faca607 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -97,6 +97,7 @@ import {LogoutComponent} from "./auth/logout.component" import {NgIdleKeepaliveModule} from "@ng-idle/keepalive" import {LabelWithSelectComponent} from "./table/skills-library-table/label-with-select.component" import {LibraryExportComponent} from "./navigation/libraryexport.component" +import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" export function initializeApp( appConfig: AppConfig, @@ -206,7 +207,8 @@ export function initializeApp( AuditLogComponent, OccupationsCardSectionComponent, CheckerComponent, - LabelWithSelectComponent + LabelWithSelectComponent, + MyWorkspaceComponent, ], imports: [ NgIdleKeepaliveModule.forRoot(), diff --git a/ui/src/app/my-workspace/my-workspace.component.html b/ui/src/app/my-workspace/my-workspace.component.html new file mode 100644 index 000000000..b64a93059 --- /dev/null +++ b/ui/src/app/my-workspace/my-workspace.component.html @@ -0,0 +1 @@ +

    my-workspace works!

    diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts new file mode 100644 index 000000000..52745586c --- /dev/null +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing" + +import { MyWorkspaceComponent } from "./my-workspace.component" + +describe("MyWorkspaceComponent", () => { + let component: MyWorkspaceComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ MyWorkspaceComponent ] + }) + .compileComponents() + }) + + beforeEach(() => { + fixture = TestBed.createComponent(MyWorkspaceComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it("should create", () => { + expect(component).toBeTruthy() + }) +}) diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts new file mode 100644 index 000000000..4bfd10b36 --- /dev/null +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -0,0 +1,35 @@ +import {Component, Inject, LOCALE_ID, OnInit} from "@angular/core" +import {ManageCollectionComponent} from "../collection/detail/manage-collection.component" +import {RichSkillService} from "../richskill/service/rich-skill.service" +import {ToastService} from "../toast/toast.service" +import {CollectionService} from "../collection/service/collection.service" +import {ActivatedRoute, Router} from "@angular/router" +import {Title} from "@angular/platform-browser" +import {AuthService} from "../auth/auth-service" + +@Component({ + selector: "app-my-workspace", + templateUrl: "../collection/detail/manage-collection.component.html" +}) +export class MyWorkspaceComponent extends ManageCollectionComponent implements OnInit { + + constructor( + protected router: Router, + protected richSkillService: RichSkillService, + protected toastService: ToastService, + protected collectionService: CollectionService, + protected route: ActivatedRoute, + protected titleService: Title, + protected authService: AuthService, + @Inject(LOCALE_ID) protected locale: string + ) { + super(router, richSkillService, toastService, collectionService, route, titleService, authService, locale) + this.uuidParam = "a11efb86-1650-4ecd-ad86-9c111f4b1fbb" + } + + ngOnInit(): void { + console.log("child on init") + this.reloadCollection() + } + +} From 591f05023d5f724d99865906de62df40e51bd0e0 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 27 Jan 2023 11:26:01 -0600 Subject: [PATCH 006/150] Working on submenu in button --- .../detail/manage-collection.component.ts | 3 ++ .../richskill/list/skills-list.component.ts | 18 +++++-- .../action-bar-item.component.html | 28 +++++++---- .../action-bar-item.component.ts | 3 +- .../action-bar-item.components.scss | 50 +++++++++++++++++++ .../has-action-definitions.ts | 12 ++++- 6 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 ui/src/app/table/skills-library-table/action-bar-item.components.scss diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index 6be718e07..d047b4046 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -86,7 +86,10 @@ export class ManageCollectionComponent extends SkillsListComponent implements On } reloadCollection(): void { + console.log("reload collection") + console.log(this.uuidParam) this.collectionService.getCollectionByUUID(this.uuidParam ?? "").subscribe(collection => { + console.log({collection}) this.titleService.setTitle(`${collection.name} | Collection | ${this.whitelabel.toolName}`) this.collection = collection diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 7cfd17ecc..2c6197f3a 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -246,11 +246,20 @@ export class SkillsListComponent extends QuickLinksHelper { if (this.showAddToCollection) { actions.push(new TableActionDefinition({ - label: "Add to Collection", - icon: "collection", + label: "Add to", + icon: "add", primary: true, - callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), - visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) + // callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), + visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill), + menu: [ + { + label: "Add to Collection", + callback: () => this.handleClickAddCollection(new TableActionDefinition({}), undefined), + }, + { + label: "Add to Workspace" + } + ] })) } else { actions.push(new TableActionDefinition({ @@ -275,6 +284,7 @@ export class SkillsListComponent extends QuickLinksHelper { } protected handleClickAddCollection(action: TableActionDefinition, skill?: ApiSkillSummary): boolean { + console.log("handleClickAddCollection") const selection = this.getSelectedSkills(skill) this.router.navigate(["/collections/add-skills"], { state: { diff --git a/ui/src/app/table/skills-library-table/action-bar-item.component.html b/ui/src/app/table/skills-library-table/action-bar-item.component.html index 2ed05b69a..ee5c4130d 100644 --- a/ui/src/app/table/skills-library-table/action-bar-item.component.html +++ b/ui/src/app/table/skills-library-table/action-bar-item.component.html @@ -1,16 +1,26 @@ - + +
    + + +
    +
    +
    + diff --git a/ui/src/app/table/skills-library-table/action-bar-item.component.ts b/ui/src/app/table/skills-library-table/action-bar-item.component.ts index 1165c8cd7..bdce117f0 100644 --- a/ui/src/app/table/skills-library-table/action-bar-item.component.ts +++ b/ui/src/app/table/skills-library-table/action-bar-item.component.ts @@ -3,7 +3,8 @@ import {TableActionDefinition} from "./has-action-definitions"; @Component({ selector: "app-action-bar-item", - templateUrl: "./action-bar-item.component.html" + templateUrl: "./action-bar-item.component.html", + styleUrls: ["./action-bar-item.components.scss"] }) export class ActionBarItemComponent implements OnInit { @Input() action: TableActionDefinition | undefined diff --git a/ui/src/app/table/skills-library-table/action-bar-item.components.scss b/ui/src/app/table/skills-library-table/action-bar-item.components.scss new file mode 100644 index 000000000..1605c5f7d --- /dev/null +++ b/ui/src/app/table/skills-library-table/action-bar-item.components.scss @@ -0,0 +1,50 @@ +.dropbtn { + color: white; + padding: 16px; + font-size: 16px; + border: none; +} + +.dropup { + position: relative; + display: inline-block; +} + +.dropup-content { + display: none; + position: absolute; + background-color: #f1f1f1; + min-width: 160px; + bottom: 50px; + z-index: 1; +} + +.dropup-content a { + color: black; + padding: 12px 16px; + text-decoration: none; + display: block; +} + +.dropup-content a:hover { + background-color: #ccc; + margin-bottom: 20px; +} + +.dropup:hover .dropup-content.dropup-content-visible { + margin-left: -40px; + display: block; + margin-bottom: 30px; +} + +.dropup-item { + color: black; + padding-left: 10%; + padding-top: 5%; + padding-bottom: 5%; +} + +hr { + border: 0.5px solid gray; + margin: 1px 5px; +} diff --git a/ui/src/app/table/skills-library-table/has-action-definitions.ts b/ui/src/app/table/skills-library-table/has-action-definitions.ts index ba3cbd5a7..c4b98fe2e 100644 --- a/ui/src/app/table/skills-library-table/has-action-definitions.ts +++ b/ui/src/app/table/skills-library-table/has-action-definitions.ts @@ -1,10 +1,18 @@ import {Component, Input} from "@angular/core"; +export interface ITableActionDefinitionSubMenu { + label?: string, + icon?: string, + callback?: () => void + visible?: () => boolean +} + interface IActionDefinition { label?: string icon?: string primary?: boolean offset?: boolean + menu?: ITableActionDefinitionSubMenu[] callback?: (actionDefinition: TableActionDefinition, data?: any) => void visible?: (data?: any) => boolean } @@ -14,16 +22,18 @@ export class TableActionDefinition { icon: string = "dismiss" primary: boolean = false offset: boolean = false + menu?: ITableActionDefinitionSubMenu[] callback?: ((actionDefinition: TableActionDefinition, data?: any) => void) visible?: (data?: any) => boolean - constructor({label, icon, primary, offset, callback, visible}: IActionDefinition) { + constructor({label, icon, primary, offset, callback, visible, menu}: IActionDefinition) { this.label = label ?? "" this.icon = icon ?? "" this.callback = callback this.visible = visible this.primary = primary ?? false this.offset = offset ?? false + this.menu = menu ?? [] } fire(data?: any): void { From 472b446e251348ded7e86c53d87b1c8a0ef65e2f Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 27 Jan 2023 17:44:13 -0600 Subject: [PATCH 007/150] Update super constructor --- .../collection-skill-search.component.ts | 2 +- .../detail/manage-collection.component.ts | 5 +--- .../my-workspace/my-workspace.component.ts | 2 +- .../library/rich-skills-library.component.ts | 4 +++- .../richskill/list/skills-list.component.ts | 23 +++++++++++++++---- .../rich-skill-search-results.component.ts | 4 +++- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/ui/src/app/collection/collection-skill-search.component.ts b/ui/src/app/collection/collection-skill-search.component.ts index b990110ee..9b3f309b2 100644 --- a/ui/src/app/collection/collection-skill-search.component.ts +++ b/ui/src/app/collection/collection-skill-search.component.ts @@ -44,7 +44,7 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen protected toastService: ToastService, protected authService: AuthService, ) { - super(router, richSkillService, toastService, authService) + super(router, richSkillService, collectionService, toastService, authService) this.titleService.setTitle(`Add RSDs to Collection | ${this.whitelabel.toolName}`) this.uuidParam = this.route.snapshot.paramMap.get("uuid") || undefined diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index d047b4046..72416d643 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -68,7 +68,7 @@ export class ManageCollectionComponent extends SkillsListComponent implements On protected authService: AuthService, @Inject(LOCALE_ID) protected locale: string ) { - super(router, richSkillService, toastService, authService) + super(router, richSkillService, collectionService, toastService, authService) } ngOnInit(): void { @@ -86,10 +86,7 @@ export class ManageCollectionComponent extends SkillsListComponent implements On } reloadCollection(): void { - console.log("reload collection") - console.log(this.uuidParam) this.collectionService.getCollectionByUUID(this.uuidParam ?? "").subscribe(collection => { - console.log({collection}) this.titleService.setTitle(`${collection.name} | Collection | ${this.whitelabel.toolName}`) this.collection = collection diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 4bfd10b36..0b33a2345 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -24,7 +24,7 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O @Inject(LOCALE_ID) protected locale: string ) { super(router, richSkillService, toastService, collectionService, route, titleService, authService, locale) - this.uuidParam = "a11efb86-1650-4ecd-ad86-9c111f4b1fbb" + this.uuidParam = "4fafd06d-7fd1-498c-90e7-e70021a0bfc0" } ngOnInit(): void { diff --git a/ui/src/app/richskill/library/rich-skills-library.component.ts b/ui/src/app/richskill/library/rich-skills-library.component.ts index 1e7be0b75..4bd92b184 100644 --- a/ui/src/app/richskill/library/rich-skills-library.component.ts +++ b/ui/src/app/richskill/library/rich-skills-library.component.ts @@ -7,6 +7,7 @@ import {Router} from "@angular/router" import {determineFilters} from "../../PublishStatus" import {Title} from "@angular/platform-browser" import {AuthService} from "../../auth/auth-service" +import {CollectionService} from "../../collection/service/collection.service" @Component({ selector: "app-rich-skills-library", @@ -19,11 +20,12 @@ export class RichSkillsLibraryComponent extends SkillsListComponent implements O constructor( protected router: Router, protected richSkillService: RichSkillService, + protected collectionService: CollectionService, protected toastService: ToastService, protected titleService: Title, protected authService: AuthService ) { - super(router, richSkillService, toastService, authService) + super(router, richSkillService, collectionService, toastService, authService) } ngOnInit(): void { diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 2c6197f3a..a58f2df0a 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -1,4 +1,4 @@ -import {ApiSearch, PaginatedSkills} from "../service/rich-skill-search.service"; +import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../service/rich-skill-search.service" import {ApiSkillSummary} from "../ApiSkillSummary"; import {checkArchived, determineFilters, PublishStatus} from "../../PublishStatus"; import {TableActionDefinition} from "../../table/skills-library-table/has-action-definitions"; @@ -14,6 +14,7 @@ import {ExtrasSelectedSkillsState} from "../../collection/add-skills-collection. import {TableActionBarComponent} from "../../table/skills-library-table/table-action-bar.component"; import {AuthService} from "../../auth/auth-service"; import {ButtonAction} from "../../auth/auth-roles"; +import {CollectionService} from "../../collection/service/collection.service" @Component({ @@ -46,6 +47,7 @@ export class SkillsListComponent extends QuickLinksHelper { constructor(protected router: Router, protected richSkillService: RichSkillService, + protected collectionService: CollectionService, protected toastService: ToastService, protected authService: AuthService, ) { @@ -249,15 +251,15 @@ export class SkillsListComponent extends QuickLinksHelper { label: "Add to", icon: "add", primary: true, - // callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill), menu: [ { label: "Add to Collection", - callback: () => this.handleClickAddCollection(new TableActionDefinition({}), undefined), + callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), }, { - label: "Add to Workspace" + label: "Add to Workspace", + callback: () => this.handleClickAddToWorkspace() } ] })) @@ -283,6 +285,19 @@ export class SkillsListComponent extends QuickLinksHelper { return false } + protected handleClickAddToWorkspace(): void { + const skillListUpdate = new ApiSkillListUpdate({add: new ApiSearch({uuids: this.getSelectedSkills()?.map(i => i.uuid)})}) + this.toastService.showBlockingLoader() + this.collectionService.updateSkillsWithResult("4fafd06d-7fd1-498c-90e7-e70021a0bfc0", skillListUpdate).subscribe(result => { + if (result) { + const message = `You added ${result.modifiedCount} RSDs to the collection.` + this.toastService.showToast("Success!", message) + this.toastService.hideBlockingLoader() + // this.return() + } + }) + } + protected handleClickAddCollection(action: TableActionDefinition, skill?: ApiSkillSummary): boolean { console.log("handleClickAddCollection") const selection = this.getSelectedSkills(skill) diff --git a/ui/src/app/search/rich-skill-search-results.component.ts b/ui/src/app/search/rich-skill-search-results.component.ts index 2b6198ba1..07bd66f31 100644 --- a/ui/src/app/search/rich-skill-search-results.component.ts +++ b/ui/src/app/search/rich-skill-search-results.component.ts @@ -13,6 +13,7 @@ import {Title} from "@angular/platform-browser"; import {AuthService} from "../auth/auth-service"; import {formatDate} from "@angular/common" import * as FileSaver from "file-saver" +import {CollectionService} from "../collection/service/collection.service" @Component({ @@ -32,6 +33,7 @@ export class RichSkillSearchResultsComponent extends SkillsListComponent impleme constructor(protected router: Router, protected richSkillService: RichSkillService, + protected collectionService: CollectionService, protected toastService: ToastService, protected searchService: SearchService, protected route: ActivatedRoute, @@ -39,7 +41,7 @@ export class RichSkillSearchResultsComponent extends SkillsListComponent impleme protected authService: AuthService, @Inject(LOCALE_ID) protected locale: string ) { - super(router, richSkillService, toastService, authService) + super(router, richSkillService, collectionService, toastService, authService) this.searchService.searchQuery$.subscribe(apiSearch => this.handleNewSearch(apiSearch) ) } From ea41d5d06cfedc10b43038646fb2f153bcc94001 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 27 Jan 2023 17:44:26 -0600 Subject: [PATCH 008/150] Update tests --- .../my-workspace.component.spec.ts | 29 +++++++++++++++++-- .../list/skills-list.component.spec.ts | 10 +++++-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index 52745586c..947f75695 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -1,6 +1,17 @@ import { ComponentFixture, TestBed } from "@angular/core/testing" import { MyWorkspaceComponent } from "./my-workspace.component" +import {RouterTestingModule} from "@angular/router/testing" +import {HttpClientModule} from "@angular/common/http" +import {AuthService} from "../auth/auth-service" +import {RichSkillService} from "../richskill/service/rich-skill.service" +import {AuthServiceStub, CollectionServiceStub, EnvironmentServiceStub, RichSkillServiceStub} from "../../../test/resource/mock-stubs" +import {HttpClientTestingModule} from "@angular/common/http/testing" +import {AppConfig} from "../app.config" +import {Title} from "@angular/platform-browser" +import {ToastService} from "../toast/toast.service" +import {EnvironmentService} from "../core/environment.service" +import {CollectionService} from "../collection/service/collection.service" describe("MyWorkspaceComponent", () => { let component: MyWorkspaceComponent @@ -8,9 +19,21 @@ describe("MyWorkspaceComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ MyWorkspaceComponent ] - }) - .compileComponents() + imports: [ + RouterTestingModule, + HttpClientTestingModule, + ], + declarations: [ MyWorkspaceComponent ], + providers: [ + AppConfig, + Title, + ToastService, + { provide: EnvironmentService, useClass: EnvironmentServiceStub }, // Example of using a service stub + { provide: RichSkillService, useClass: RichSkillServiceStub }, + { provide: CollectionService, useClass: CollectionServiceStub }, + { provide: AuthService, useClass: AuthServiceStub }, + ] + }).compileComponents() }) beforeEach(() => { diff --git a/ui/src/app/richskill/list/skills-list.component.spec.ts b/ui/src/app/richskill/list/skills-list.component.spec.ts index 8ba21c42e..1e4a7335b 100644 --- a/ui/src/app/richskill/list/skills-list.component.spec.ts +++ b/ui/src/app/richskill/list/skills-list.component.spec.ts @@ -12,6 +12,8 @@ import { ApiSearch, PaginatedSkills } from "../service/rich-skill-search.service import { RichSkillService } from "../service/rich-skill.service" import { SkillsListComponent } from "./skills-list.component" import {AuthService} from "../../auth/auth-service"; +import {CollectionService} from "../../collection/service/collection.service" +import {HttpClient, HttpClientModule, HttpHandler} from "@angular/common/http" @Component({ @@ -57,6 +59,7 @@ describe("SkillsListComponent", () => { ConcreteComponent ], imports: [ + HttpClientModule, RouterTestingModule.withRoutes([ { path: "collections/add-skills", component: SkillsListComponent } ]) @@ -64,7 +67,7 @@ describe("SkillsListComponent", () => { providers: [ ToastService, { provide: RichSkillService, useClass: RichSkillServiceStub }, - { provide: AuthService, useClass: AuthServiceStub }, + { provide: AuthService, useClass: AuthServiceStub } ] }) @@ -396,8 +399,9 @@ describe("SkillsListComponent", () => { tableActions = component.tableActions() let skill4 = createMockSkillSummary("id4", PublishStatus.Archived) let action4 = tableActions[4] - expect(action4.label).toEqual("Add to Collection") - expect(action4 && action4.callback).toBeTruthy() + expect(action4.label).toEqual("Add to") + expect(action4).toBeTruthy() + expect(action4.callback).toBeUndefined() expect(action4.callback?.(action4, skill4)).toBeFalsy() // Always false expect(action4.visible?.(skill4)).toBeTruthy() // There are selected skills From 80b283f073c3cd3eb5563158b360de4d7c0dfe03 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 27 Jan 2023 17:45:26 -0600 Subject: [PATCH 009/150] Update ITableActionDefinitionSubMenu --- .../table/skills-library-table/action-bar-item.component.html | 2 +- .../skills-library-table/action-bar-item.components.scss | 4 ++++ .../app/table/skills-library-table/has-action-definitions.ts | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/src/app/table/skills-library-table/action-bar-item.component.html b/ui/src/app/table/skills-library-table/action-bar-item.component.html index ee5c4130d..a5df37063 100644 --- a/ui/src/app/table/skills-library-table/action-bar-item.component.html +++ b/ui/src/app/table/skills-library-table/action-bar-item.component.html @@ -17,7 +17,7 @@
    -
    diff --git a/ui/src/app/table/skills-library-table/action-bar-item.components.scss b/ui/src/app/table/skills-library-table/action-bar-item.components.scss index 1605c5f7d..2e6e46569 100644 --- a/ui/src/app/table/skills-library-table/action-bar-item.components.scss +++ b/ui/src/app/table/skills-library-table/action-bar-item.components.scss @@ -44,6 +44,10 @@ padding-bottom: 5%; } +.dropup-item:hover { + text-decoration: underline; +} + hr { border: 0.5px solid gray; margin: 1px 5px; diff --git a/ui/src/app/table/skills-library-table/has-action-definitions.ts b/ui/src/app/table/skills-library-table/has-action-definitions.ts index c4b98fe2e..03bd5bcae 100644 --- a/ui/src/app/table/skills-library-table/has-action-definitions.ts +++ b/ui/src/app/table/skills-library-table/has-action-definitions.ts @@ -1,9 +1,10 @@ import {Component, Input} from "@angular/core"; +import {ApiSkillSummary} from "../../richskill/ApiSkillSummary" export interface ITableActionDefinitionSubMenu { label?: string, icon?: string, - callback?: () => void + callback?: (actionDefinition: TableActionDefinition, data?: any) => void visible?: () => boolean } From 47186e9c5b8e9ff583358e8c45fd966f8466cd7f Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 30 Jan 2023 12:25:31 -0600 Subject: [PATCH 010/150] Add test - Add test for header.component.ts. - Use this.router.url instead of window.location.pathname. --- .../app/navigation/header.component.spec.ts | 75 +++++++++++++++++++ ui/src/app/navigation/header.component.ts | 4 +- 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 ui/src/app/navigation/header.component.spec.ts diff --git a/ui/src/app/navigation/header.component.spec.ts b/ui/src/app/navigation/header.component.spec.ts new file mode 100644 index 000000000..8ae3066da --- /dev/null +++ b/ui/src/app/navigation/header.component.spec.ts @@ -0,0 +1,75 @@ +import {ComponentFixture, fakeAsync, TestBed, tick} from "@angular/core/testing" +import {HeaderComponent} from "./header.component" +import {AuthService} from "../auth/auth-service" +import {AuthServiceStub} from "../../../test/resource/mock-stubs" +import {RouterTestingModule} from "@angular/router/testing" +import {AppConfig} from "../app.config" +import {EnvironmentService} from "../core/environment.service" +import {Location} from "@angular/common" +import {ConcreteService} from "../abstract.service.spec" +import {HttpClientModule} from "@angular/common/http" +import {Router} from "@angular/router" +import {MyWorkspaceComponent} from "../my-workspace/my-workspace.component" +import {RichSkillsLibraryComponent} from "../richskill/library/rich-skills-library.component" + +describe("HeaderComponent", () => { + + let component: HeaderComponent + let fixture: ComponentFixture + let router: Router + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + HeaderComponent + ], + providers: [ + EnvironmentService, + AppConfig, + ConcreteService, + Location, + {provide: AuthService, useClass: AuthServiceStub}, + ], + imports: [ + HttpClientModule, + RouterTestingModule.withRoutes([ + { + path: "my-workspace", + component: MyWorkspaceComponent + }, + { + path: "skills", + component: RichSkillsLibraryComponent + } + ]) + ] + }).compileComponents() + }) + + beforeEach(() => { + const appConfig = TestBed.inject(AppConfig) + AppConfig.settings = appConfig.defaultConfig() + fixture = TestBed.createComponent(HeaderComponent) + component = fixture.componentInstance + router = TestBed.inject(Router) + fixture.detectChanges() + }) + + it("should be created", () => { + expect(component).toBeTruthy() + }) + + it("my workspace is active", fakeAsync(() => { + router.navigate(["/my-workspace"]) + tick() + expect(component.myWorkspaceActive).toBeTruthy() + })) + + it("my workspace is active", fakeAsync(() => { + router.navigate(["/skills"]) + tick() + expect(router).toBeTruthy() + })) + + +}) diff --git a/ui/src/app/navigation/header.component.ts b/ui/src/app/navigation/header.component.ts index 25f24dc31..e4ce2e653 100644 --- a/ui/src/app/navigation/header.component.ts +++ b/ui/src/app/navigation/header.component.ts @@ -39,11 +39,11 @@ export class HeaderComponent extends Whitelabelled implements OnInit { } get myWorkspaceActive(): boolean { - return window.location.pathname.startsWith("/my-workspace") + return this.router.url.startsWith("/my-workspace") } get skillsActive(): boolean { - return window.location.pathname.startsWith("/skills") + return this.router.url.startsWith("/skills") } handleQuicklink(elementId: string): boolean { From be3ec4bcef0badfa6bc07d533ac880ddc19cb233 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 30 Jan 2023 16:52:34 -0600 Subject: [PATCH 011/150] Workspace actions --- .../detail/manage-collection.component.html | 4 +- .../detail/manage-collection.component.ts | 4 ++ .../my-workspace.component.spec.ts | 20 ++++++---- .../my-workspace/my-workspace.component.ts | 38 ++++++++++++++++++- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/ui/src/app/collection/detail/manage-collection.component.html b/ui/src/app/collection/detail/manage-collection.component.html index ec40bb504..a245685ea 100644 --- a/ui/src/app/collection/detail/manage-collection.component.html +++ b/ui/src/app/collection/detail/manage-collection.component.html @@ -139,7 +139,7 @@

    Confirm that you want

    - Confirm that you want to delete {{this.collection?.name}} + Confirm that you want to {{collection.status === "Workspace" ? "reset" : "delete"}} {{this.collection?.name}}

    @@ -150,7 +150,7 @@

    Cancel

    diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index 72416d643..754f5b040 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -275,6 +275,10 @@ export class ManageCollectionComponent extends SkillsListComponent implements On window.open(url, "_blank") } + conertToCollectionAction(): void { + + } + publishAction(): void { if (this.uuidParam === undefined) { return } diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index 947f75695..b62471fc8 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -1,8 +1,7 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing" +import {ComponentFixture, TestBed} from "@angular/core/testing" -import { MyWorkspaceComponent } from "./my-workspace.component" +import {MyWorkspaceComponent} from "./my-workspace.component" import {RouterTestingModule} from "@angular/router/testing" -import {HttpClientModule} from "@angular/common/http" import {AuthService} from "../auth/auth-service" import {RichSkillService} from "../richskill/service/rich-skill.service" import {AuthServiceStub, CollectionServiceStub, EnvironmentServiceStub, RichSkillServiceStub} from "../../../test/resource/mock-stubs" @@ -23,15 +22,15 @@ describe("MyWorkspaceComponent", () => { RouterTestingModule, HttpClientTestingModule, ], - declarations: [ MyWorkspaceComponent ], + declarations: [MyWorkspaceComponent], providers: [ AppConfig, Title, ToastService, - { provide: EnvironmentService, useClass: EnvironmentServiceStub }, // Example of using a service stub - { provide: RichSkillService, useClass: RichSkillServiceStub }, - { provide: CollectionService, useClass: CollectionServiceStub }, - { provide: AuthService, useClass: AuthServiceStub }, + {provide: EnvironmentService, useClass: EnvironmentServiceStub}, // Example of using a service stub + {provide: RichSkillService, useClass: RichSkillServiceStub}, + {provide: CollectionService, useClass: CollectionServiceStub}, + {provide: AuthService, useClass: AuthServiceStub}, ] }).compileComponents() }) @@ -45,4 +44,9 @@ describe("MyWorkspaceComponent", () => { it("should create", () => { expect(component).toBeTruthy() }) + + it("actions definitions should be correct", () => { + expect(component.actionDefinitions().length).toEqual(4) + }) + }) diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 0b33a2345..1a3b29a41 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -6,6 +6,10 @@ import {CollectionService} from "../collection/service/collection.service" import {ActivatedRoute, Router} from "@angular/router" import {Title} from "@angular/platform-browser" import {AuthService} from "../auth/auth-service" +import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions" +import {ButtonAction} from "../auth/auth-roles" +import {PublishStatus} from "../PublishStatus" +import {size} from "lodash" @Component({ selector: "app-my-workspace", @@ -24,7 +28,7 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O @Inject(LOCALE_ID) protected locale: string ) { super(router, richSkillService, toastService, collectionService, route, titleService, authService, locale) - this.uuidParam = "4fafd06d-7fd1-498c-90e7-e70021a0bfc0" + this.uuidParam = "00ff748a-7141-47f2-aaf5-f9b8a992505f" } ngOnInit(): void { @@ -32,4 +36,36 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O this.reloadCollection() } + actionDefinitions(): TableActionDefinition[] { + this.collection ? this.collection.status = PublishStatus.Workspace : false + console.log(this.collection) + const actions = [ + new TableActionDefinition({ + label: "Add RSDs to My Workspace", + icon: this.addIcon, + callback: () => this.addSkillsAction(), + visible: () => true + }), + new TableActionDefinition({ + label: "Download as CSV", + icon: this.downloadIcon, + callback: () => this.generateCsv(this.collection?.name ?? ""), + visible: () => true + }), + new TableActionDefinition({ + label: "Convert to Collection", + icon: this.publishIcon, + callback: () => this.conertToCollectionAction(), + visible: () => true + }), + new TableActionDefinition({ + label: "Reset Collection", + icon: this.deleteIcon, + callback: () => this.deleteCollectionAction(), + visible: () => true + }) + ] + return actions + } + } From 5e7f8704df1a8dc6cec4190445c1ff99aa46408a Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 31 Jan 2023 10:49:08 -0600 Subject: [PATCH 012/150] Update PublishStatus.ts --- ui/src/app/PublishStatus.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/src/app/PublishStatus.ts b/ui/src/app/PublishStatus.ts index f1602c0cd..d15fad8c2 100644 --- a/ui/src/app/PublishStatus.ts +++ b/ui/src/app/PublishStatus.ts @@ -5,7 +5,8 @@ export enum PublishStatus { Published = "Published", Archived = "Archived", Deleted = "Deleted", - Draft = "Draft" + Draft = "Draft", + Workspace = "Workspace" } From ada1a83d4451bc458eb42ba9a5df3494c6e550f0 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Feb 2023 09:51:55 -0600 Subject: [PATCH 013/150] returning to use PublishStatus as Enum for Collection status --- .../kotlin/edu/wgu/osmt/collection/Collection.kt | 3 +-- .../edu/wgu/osmt/collection/CollectionDoc.kt | 3 +-- .../edu/wgu/osmt/collection/CollectionTable.kt | 4 ++-- .../edu/wgu/osmt/db/CollectionStatusEnum.kt | 16 ---------------- .../main/kotlin/edu/wgu/osmt/db/PublishStatus.kt | 4 ++-- .../V2023.01.26__add_status_and_owner_fields.sql | 4 ++-- 6 files changed, 8 insertions(+), 26 deletions(-) delete mode 100644 api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt index 42f3d8c69..feda18de3 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt @@ -3,7 +3,6 @@ package edu.wgu.osmt.collection import edu.wgu.osmt.auditlog.Change import edu.wgu.osmt.auditlog.Comparison import edu.wgu.osmt.db.* -import edu.wgu.osmt.db.CollectionStatusEnum import edu.wgu.osmt.keyword.Keyword import edu.wgu.osmt.keyword.KeywordDao import edu.wgu.osmt.keyword.KeywordTypeEnum @@ -22,7 +21,7 @@ data class Collection( val name: String, val author: Keyword? = null, val workspaceOwner: String? = null, - val status: Enum, + val status: Enum, override val archiveDate: LocalDateTime? = null, override val publishDate: LocalDateTime? = null ) : DatabaseData, HasUpdateDate, PublishStatusDetails { diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDoc.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDoc.kt index 7f5847106..227455172 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDoc.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDoc.kt @@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty import edu.wgu.osmt.config.INDEX_COLLECTION_DOC import edu.wgu.osmt.db.PublishStatus -import edu.wgu.osmt.db.CollectionStatusEnum import org.elasticsearch.core.Nullable import org.springframework.data.annotation.Id import org.springframework.data.elasticsearch.annotations.* @@ -76,6 +75,6 @@ data class CollectionDoc( val workspaceOwner: String?, @Field(type = Text) - val status: Enum + val status: Enum ) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt index cce555974..e445e5009 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt @@ -1,6 +1,6 @@ package edu.wgu.osmt.collection -import edu.wgu.osmt.db.CollectionStatusEnum +import edu.wgu.osmt.db.PublishStatus import edu.wgu.osmt.db.PublishStatusUpdate import edu.wgu.osmt.db.TableWithUpdate import edu.wgu.osmt.keyword.KeywordTable @@ -32,7 +32,7 @@ object CollectionTable: TableWithUpdate, PublishStatusUp val workspaceOwner = varchar("workspace_owner", 64).index() val status = customEnumeration( "status", - fromDb = { value -> CollectionStatusEnum.valueOf(value as String) }, toDb = { it.name }) + fromDb = { value -> PublishStatus.valueOf(value as String) }, toDb = { it.name }) } object CollectionSkills : Table("CollectionSkills") { diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt b/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt deleted file mode 100644 index 631aa4092..000000000 --- a/api/src/main/kotlin/edu/wgu/osmt/db/CollectionStatusEnum.kt +++ /dev/null @@ -1,16 +0,0 @@ -package edu.wgu.osmt.db - -const val WORKSPACE = "workspace" - -enum class CollectionStatusEnum(val apiValue: String) { - Published(PUBLISHED), - Archived(ARCHIVED), - Draft(DRAFT), - Workspace(WORKSPACE); - - open val displayName: String = this.name - - companion object { - fun forApiValue(apiValue: String) = CollectionStatusEnum.values().find { it.name.toLowerCase() == apiValue.toLowerCase() } - } -} diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt b/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt index 6c146a64b..8a9595a11 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt @@ -2,7 +2,7 @@ package edu.wgu.osmt.db const val UNARCHIVED = "unarchived" const val DELETED = "deleted" - +const val WORKSPACE = "workspace" const val PUBLISHED = "published" const val ARCHIVED = "archived" const val DRAFT = "draft" @@ -10,7 +10,7 @@ const val DRAFT = "draft" enum class PublishStatus(val apiValue: String) { Unarchived(UNARCHIVED), Deleted(DELETED), - + Workspace(WORKSPACE), Published(PUBLISHED), Archived(ARCHIVED), Draft(DRAFT); diff --git a/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql b/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql index 8b299b763..9dd4fcf5e 100644 --- a/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql +++ b/api/src/main/resources/db/migration/V2023.01.26__add_status_and_owner_fields.sql @@ -1,3 +1,3 @@ -ALTER TABLE Collection ADD workspace_owner VARCHAR(64) NOT NULL; -ALTER TABLE Collection ADD status enum ('Draft','Published','Archived','Workspace') NOT NULL; +ALTER TABLE Collection ADD workspace_owner VARCHAR(64) NOT NULL DEFAULT ''; +ALTER TABLE Collection ADD status enum ('unarchived','deleted','workspace','published','archived','draft') NOT NULL DEFAULT 'draft'; CREATE INDEX Collection_workspace_owner ON Collection (workspace_owner); \ No newline at end of file From 6f7483298ed8c58386d883c7c174352a584ba725 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Feb 2023 10:36:10 -0600 Subject: [PATCH 014/150] adding logic to avoid nulls in status for collection, adding owner field in ApiCollection.kt --- .../main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt | 4 ++++ .../kotlin/edu/wgu/osmt/collection/CollectionTable.kt | 4 ++-- api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt | 9 ++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt index 818426da4..3af618fba 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt @@ -63,6 +63,10 @@ class ApiCollection(private val collection: Collection, private val ss: List get() = ss.map { ApiSkillSummary.fromSkill(it, appConfig) } + @get:JsonProperty + val owner: String? + get() = collection.workspaceOwner?.let { it } + companion object { fun fromDao(collectionDao: CollectionDao, appConfig: AppConfig): ApiCollection { return ApiCollection(collectionDao.toModel(), collectionDao.skills.map{ it.toModel() }, appConfig) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt index e445e5009..e3c7f96ee 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt @@ -29,10 +29,10 @@ object CollectionTable: TableWithUpdate, PublishStatusUp onDelete = ReferenceOption.RESTRICT, onUpdate = ReferenceOption.CASCADE ).nullable() - val workspaceOwner = varchar("workspace_owner", 64).index() + val workspaceOwner = varchar("workspace_owner", 64).index().default("") val status = customEnumeration( "status", - fromDb = { value -> PublishStatus.valueOf(value as String) }, toDb = { it.name }) + fromDb = { value -> PublishStatus.valueOf(value as String) }, toDb = { it.name }).default(PublishStatus.Draft) } object CollectionSkills : Table("CollectionSkills") { diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt b/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt index ea0053a68..8325c0b25 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt @@ -1,5 +1,6 @@ package edu.wgu.osmt.db +import edu.wgu.osmt.collection.CollectionDao import org.jetbrains.exposed.dao.LongEntity import java.time.LocalDateTime import java.time.ZoneOffset @@ -25,7 +26,13 @@ interface HasPublishStatus { dao.archiveDate = LocalDateTime.now(ZoneOffset.UTC) } } - else -> {} // draft is non-op + else -> { + if (dao is CollectionDao) { + if(publishStatus != null) + dao.status = publishStatus as PublishStatus + } + + } // draft is non-op } } } From f21737ecedfa33912f081a7d605910c4d4221b8c Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Feb 2023 12:29:31 -0600 Subject: [PATCH 015/150] adding logic to populate owner field depending on the param passed when creating/updating collection --- .../osmt/collection/CollectionController.kt | 2 +- .../osmt/collection/CollectionRepository.kt | 22 +++++++++------ .../edu/wgu/osmt/csv/BatchImportRichSkill.kt | 2 +- .../kotlin/edu/wgu/osmt/db/PublishStatus.kt | 8 ++++++ .../wgu/osmt/richskill/RichSkillRepository.kt | 27 +++++++++++-------- .../edu/wgu/osmt/security/OAuthHelper.kt | 4 +++ 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt index 38c40e24f..6affaabf5 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt @@ -97,7 +97,7 @@ class CollectionController @Autowired constructor( ): List { return collectionRepository.createFromApi( apiCollectionUpdates, - richSkillRepository, oAuthHelper.readableUsername(user) + richSkillRepository, oAuthHelper.readableUsername(user), oAuthHelper.readableEmail(user) ).map { ApiCollection.fromDao(it, appConfig) } diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt index df8237c52..766d7fe1c 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt @@ -10,6 +10,7 @@ import edu.wgu.osmt.auditlog.AuditOperationType import edu.wgu.osmt.config.AppConfig import edu.wgu.osmt.db.ListFieldUpdate import edu.wgu.osmt.db.NullableFieldUpdate +import edu.wgu.osmt.db.PublishStatus import edu.wgu.osmt.keyword.KeywordRepository import edu.wgu.osmt.keyword.KeywordTypeEnum import edu.wgu.osmt.richskill.RichSkillDescriptor @@ -43,15 +44,16 @@ interface CollectionRepository { fun findById(id: Long): CollectionDao? fun findByUUID(uuid: String): CollectionDao? fun findByName(name: String): CollectionDao? - fun create(name: String, user: String): CollectionDao? - fun create(updateObject: CollectionUpdateObject, user: String): CollectionDao? + fun create(name: String, user: String, email: String): CollectionDao? + fun create(updateObject: CollectionUpdateObject, user: String, email: String): CollectionDao? fun update(updateObject: CollectionUpdateObject, user: String): CollectionDao? fun remove(uuid: String): ApiBatchResult fun createFromApi( apiUpdates: List, richSkillRepository: RichSkillRepository, - user: String + user: String, + email: String, ): List fun collectionUpdateObjectFromApi( @@ -107,11 +109,11 @@ class CollectionRepositoryImpl @Autowired constructor( return query?.let { dao.wrapRow(it) } } - override fun create(name: String, user: String): CollectionDao? { - return create(CollectionUpdateObject(name = name), user) + override fun create(name: String, user: String, email: String): CollectionDao? { + return create(CollectionUpdateObject(name = name), user, email) } - override fun create(updateObject: CollectionUpdateObject, user: String): CollectionDao? { + override fun create(updateObject: CollectionUpdateObject, user: String, email: String): CollectionDao? { if (updateObject.name.isNullOrBlank()) { return null } @@ -125,6 +127,9 @@ class CollectionRepositoryImpl @Autowired constructor( } updateObject.copy(id = newCollection.id.value).applyToDao(newCollection) + if(PublishStatus.Workspace == newCollection.status) { + newCollection.workspaceOwner = email + } newCollection.let { collectionEsRepo.save(it.toDoc()) @@ -238,7 +243,8 @@ class CollectionRepositoryImpl @Autowired constructor( override fun createFromApi( apiUpdates: List, richSkillRepository: RichSkillRepository, - user: String + user: String, + email: String ): List { // pre validate all rows val allErrors = apiUpdates.mapIndexed { i, updateDto -> @@ -251,7 +257,7 @@ class CollectionRepositoryImpl @Autowired constructor( // create records val newSkills = apiUpdates.map { update -> val updateObject = collectionUpdateObjectFromApi(update, richSkillRepository) - create(updateObject, user) + create(updateObject, user, email) } return newSkills.filterNotNull() } diff --git a/api/src/main/kotlin/edu/wgu/osmt/csv/BatchImportRichSkill.kt b/api/src/main/kotlin/edu/wgu/osmt/csv/BatchImportRichSkill.kt index 2135298a2..9f1342e9c 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/csv/BatchImportRichSkill.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/csv/BatchImportRichSkill.kt @@ -118,7 +118,7 @@ class BatchImportRichSkill: CsvImport { fun parseCollections(rowValue: String?): List? { return splitField(rowValue)?.filter { it.isNotBlank() }?.mapNotNull { collectionName -> val collection = collectionRepository.findByName(collectionName) - collection ?: collectionRepository.create(CollectionUpdateObject(name = collectionName, author = NullableFieldUpdate(keywordRepository.getDefaultAuthor())), user) + collection ?: collection?.let { collectionRepository.create(CollectionUpdateObject(name = collectionName, author = NullableFieldUpdate(keywordRepository.getDefaultAuthor())), user, email = it.workspaceOwner) } } } diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt b/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt index 8a9595a11..75658e0e0 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt @@ -1,5 +1,7 @@ package edu.wgu.osmt.db +import com.fasterxml.jackson.annotation.JsonProperty + const val UNARCHIVED = "unarchived" const val DELETED = "deleted" const val WORKSPACE = "workspace" @@ -8,11 +10,17 @@ const val ARCHIVED = "archived" const val DRAFT = "draft" enum class PublishStatus(val apiValue: String) { + @JsonProperty("unarchived") Unarchived(UNARCHIVED), + @JsonProperty("deleted") Deleted(DELETED), + @JsonProperty("workspace") Workspace(WORKSPACE), + @JsonProperty("published") Published(PUBLISHED), + @JsonProperty("archived") Archived(ARCHIVED), + @JsonProperty("draft") Draft(DRAFT); companion object { diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillRepository.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillRepository.kt index 3dbc158a3..254144a3f 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillRepository.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillRepository.kt @@ -1,7 +1,11 @@ package edu.wgu.osmt.richskill import edu.wgu.osmt.api.FormValidationException -import edu.wgu.osmt.api.model.* +import edu.wgu.osmt.api.model.ApiAlignmentListUpdate +import edu.wgu.osmt.api.model.ApiBatchResult +import edu.wgu.osmt.api.model.ApiReferenceListUpdate +import edu.wgu.osmt.api.model.ApiSkillUpdate +import edu.wgu.osmt.api.model.ApiStringListUpdate import edu.wgu.osmt.auditlog.AuditLog import edu.wgu.osmt.auditlog.AuditLogRepository import edu.wgu.osmt.auditlog.AuditOperationType @@ -41,9 +45,9 @@ interface RichSkillRepository : PaginationHelpers { fun findManyByUUIDs(uuids: List): List? fun create(updateObject: RsdUpdateObject, user: String): RichSkillDescriptorDao? - fun createFromApi(skillUpdates: List, user: String): List - fun updateFromApi(existingSkillId: Long, skillUpdate: ApiSkillUpdate, user: String): RichSkillDescriptorDao? - fun rsdUpdateFromApi(skillUpdate: ApiSkillUpdate, user: String): RsdUpdateObject + fun createFromApi(skillUpdates: List, user: String, userEmail: String): List + fun updateFromApi(existingSkillId: Long, skillUpdate: ApiSkillUpdate, user: String, email: String): RichSkillDescriptorDao? + fun rsdUpdateFromApi(skillUpdate: ApiSkillUpdate, user: String, userEmail: String): RsdUpdateObject fun changeStatusesForTask(task: PublishTask): ApiBatchResult @@ -163,7 +167,7 @@ class RichSkillRepositoryImpl @Autowired constructor( return newRsd } - override fun createFromApi(skillUpdates: List, user: String): List { + override fun createFromApi(skillUpdates: List, user: String, userEmail: String): List { // pre validate all rows val allErrors = skillUpdates.mapIndexed { i, updateDto -> updateDto.validateForCreation(i) @@ -174,7 +178,7 @@ class RichSkillRepositoryImpl @Autowired constructor( // create records val newSkills = skillUpdates.map { update -> - val rsdUpdateObject = rsdUpdateFromApi(update, user) + val rsdUpdateObject = rsdUpdateFromApi(update, user, userEmail) create(rsdUpdateObject, user) } return newSkills.filterNotNull() @@ -183,21 +187,22 @@ class RichSkillRepositoryImpl @Autowired constructor( override fun updateFromApi( existingSkillId: Long, skillUpdate: ApiSkillUpdate, - user: String + user: String, + email: String ): RichSkillDescriptorDao? { val errors = skillUpdate.validate(0) if (errors?.isNotEmpty() == true) { throw FormValidationException("Invalid SkillUpdateDescriptor", errors) } - val rsdUpdateObject = rsdUpdateFromApi(skillUpdate, user) + val rsdUpdateObject = rsdUpdateFromApi(skillUpdate, user, email) val updateObjectWithId = rsdUpdateObject.copy( id = existingSkillId ) return update(updateObjectWithId, user) } - override fun rsdUpdateFromApi(skillUpdate: ApiSkillUpdate, user: String): RsdUpdateObject { + override fun rsdUpdateFromApi(skillUpdate: ApiSkillUpdate, user: String, email: String): RsdUpdateObject { val authorKeyword = skillUpdate.author?.let { keywordRepository.findOrCreate(KeywordTypeEnum.Author, value = it) } @@ -216,13 +221,13 @@ class RichSkillRepositoryImpl @Autowired constructor( skillUpdate.collections?.let { slu -> slu.add?.mapNotNull { - collectionRepository.findByName(it) ?: collectionRepository.create(it, user) + collectionRepository.findByName(it) ?: collectionRepository.create(it, user, email) }?.let { addingCollections.addAll(it) } slu.remove?.mapNotNull { - collectionRepository.findByName(it) ?: collectionRepository.create(it, user) + collectionRepository.findByName(it) ?: collectionRepository.create(it, user, email) }?.let { removingCollections.addAll(it) } diff --git a/api/src/main/kotlin/edu/wgu/osmt/security/OAuthHelper.kt b/api/src/main/kotlin/edu/wgu/osmt/security/OAuthHelper.kt index 4b2cf6040..8937f4dc5 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/security/OAuthHelper.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/security/OAuthHelper.kt @@ -21,6 +21,10 @@ class OAuthHelper { return jwt?.claims?.get("name") as String? ?: default } + fun readableEmail(jwt: Jwt?, default: String = UNAUTHENTICATED_USERNAME): String { + return jwt?.claims?.get("email") as String? ?: default + } + fun hasRole(role: String): Boolean { val roles = SecurityContextHolder.getContext().authentication.authorities.toString() return roles.contains(role); From b63786773adccf092c7536d450e3fd1c78e4f896 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Feb 2023 12:32:01 -0600 Subject: [PATCH 016/150] adding logic to populate owner field depending on the param passed when creating/updating collection --- .../richskill/CreateSkillsTaskProcessor.kt | 2 +- .../wgu/osmt/richskill/RichSkillController.kt | 4 +- api/src/main/kotlin/edu/wgu/osmt/task/Task.kt | 1 + .../collection/CollectionRepositoryTest.kt | 26 ++++--- .../ElasticSearchReindexerTest.kt | 2 +- .../osmt/richskill/RichSkillRepositoryTest.kt | 73 +++++++++++++++---- 6 files changed, 77 insertions(+), 31 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/CreateSkillsTaskProcessor.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/CreateSkillsTaskProcessor.kt index 28778d3d0..6f5a3411a 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/CreateSkillsTaskProcessor.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/CreateSkillsTaskProcessor.kt @@ -37,7 +37,7 @@ class CreateSkillsTaskProcessor { fun process(task: CreateSkillsTask) { logger.info("Started processing createSkillsTask uuid: ${task.uuid}") - val results = richSkillRepository.createFromApi(task.apiSkillUpdates, task.userString).map { + val results = richSkillRepository.createFromApi(task.apiSkillUpdates, task.userString, task.userEmail).map { it.uuid } diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt index 707543dc3..f506c8416 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt @@ -82,7 +82,7 @@ class RichSkillController @Autowired constructor( @RequestBody apiSkillUpdates: List, @AuthenticationPrincipal user: Jwt? ): HttpEntity { - val task = CreateSkillsTask(apiSkillUpdates) + val task = CreateSkillsTask(apiSkillUpdates, oAuthHelper.readableUsername(user), oAuthHelper.readableEmail(user)) taskMessageService.enqueueJob(TaskMessageService.createSkills, task) return Task.processingResponse(task) } @@ -150,7 +150,7 @@ class RichSkillController @Autowired constructor( ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) val updatedSkill = - richSkillRepository.updateFromApi(existingSkill.id.value, skillUpdate, oAuthHelper.readableUsername(user)) + richSkillRepository.updateFromApi(existingSkill.id.value, skillUpdate, oAuthHelper.readableUsername(user), oAuthHelper.readableEmail(user)) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) return ApiSkill.fromDao(updatedSkill, appConfig) diff --git a/api/src/main/kotlin/edu/wgu/osmt/task/Task.kt b/api/src/main/kotlin/edu/wgu/osmt/task/Task.kt index 3f8c815f7..d549b17e6 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/task/Task.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/task/Task.kt @@ -85,6 +85,7 @@ data class ExportSkillsToCsvTask( data class CreateSkillsTask( val apiSkillUpdates: List = listOf(), val userString: String = "", + val userEmail: String = "", override val uuid: String = UUID.randomUUID().toString(), override val start: Date = Date(), override val result: List? = null, diff --git a/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt b/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt index 3f32415d2..ab47c75a2 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt @@ -33,19 +33,21 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes val userString = "unittestuser" + val userEmail = "unit@test.user" + @Test fun `should not create a blank collection`() { - assertThat(collectionRepository.create(CollectionUpdateObject(), userString)).isNull() - assertThat(collectionRepository.create(CollectionUpdateObject(name=""), userString)).isNull() - assertThat(collectionRepository.create(CollectionUpdateObject(name=" "), userString)).isNull() + assertThat(collectionRepository.create(CollectionUpdateObject(), userString, userEmail)).isNull() + assertThat(collectionRepository.create(CollectionUpdateObject(name=""), userString, userEmail)).isNull() + assertThat(collectionRepository.create(CollectionUpdateObject(name=" "), userString, userEmail)).isNull() } @Test fun `should create collections from ApiCollectionUpdate objects`() { val count = 1 val updates = (1..count).toList().map { random_collection_update() } - val results = collectionRepository.createFromApi(updates, richSkillRepository, userString) + val results = collectionRepository.createFromApi(updates, richSkillRepository, userString, userEmail) results.forEachIndexed { i, collectionDao -> val collectionAndSkills = CollectionAndRichSkills.fromDao(collectionDao) @@ -91,7 +93,7 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes @Test fun `should update an existing collection from an ApiCollectionUpdate`() { val originalUpdate = random_collection_update() - val originalDao = collectionRepository.createFromApi(listOf(originalUpdate), richSkillRepository, userString).first() + val originalDao = collectionRepository.createFromApi(listOf(originalUpdate), richSkillRepository, userString, userEmail).first() var newUpdate = random_collection_update() newUpdate = newUpdate.copy( @@ -115,11 +117,11 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes ) } - val collectionDao = collectionRepository.create(UUID.randomUUID().toString(), userString) + val collectionDao = collectionRepository.create(UUID.randomUUID().toString(), userString, userEmail) val collection = collectionDao!!.toModel() - val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString) - val knownDaos = richSkillRepository.createFromApi(knownUpdates, userString) + val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString, userEmail) + val knownDaos = richSkillRepository.createFromApi(knownUpdates, userString, userEmail) assertThat(skillDaos.size + knownDaos.size).isEqualTo(totalSkillCount) val task = UpdateCollectionSkillsTask( @@ -152,7 +154,7 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes fun testChangeStatusesForTask() { // Arrange val collectionsCount = 2 - val collections = (1..collectionsCount).toList().map { collectionRepository.create(UUID.randomUUID().toString(), userString)!!.toModel() } + val collections = (1..collectionsCount).toList().map { collectionRepository.create(UUID.randomUUID().toString(), userString, userEmail)!!.toModel() } val task = PublishTask( search=ApiSearch(uuids= collections.map { it.uuid }), @@ -172,10 +174,10 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes val skillCount = 3 val skills = (1..skillCount).toList().map { TestObjectHelpers.apiSkillUpdateGenerator() } - val collectionDao = collectionRepository.create(UUID.randomUUID().toString(), userString) + val collectionDao = collectionRepository.create(UUID.randomUUID().toString(), userString, userEmail) val collection = collectionDao!!.toModel() - richSkillRepository.createFromApi(skills, userString) + richSkillRepository.createFromApi(skills, userString, userEmail) val task = PublishTask( search=ApiSearch(), @@ -193,7 +195,7 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes @Test fun `remove finds and successfully removes an existing collection`() { // Arrange - val collection = collectionRepository.create(UUID.randomUUID().toString(), userString)!!.toModel() + val collection = collectionRepository.create(UUID.randomUUID().toString(), userString, userEmail)!!.toModel() val updateObject = RsdUpdateObject(name = "test skill", statement = testUser) val skillDao = richSkillRepository.create(updateObject, testUser) collection.id?.let { CollectionSkills.create(it, skillDao!!.id.value) } diff --git a/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/ElasticSearchReindexerTest.kt b/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/ElasticSearchReindexerTest.kt index 46500fbc4..52f796a0b 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/ElasticSearchReindexerTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/ElasticSearchReindexerTest.kt @@ -43,7 +43,7 @@ internal class ElasticSearchReindexerTest @Autowired constructor( // Arrange // This creates 1 skill, 3 collections, 17 keywords and 3 jobCodes richSkillRepository.createFromApi( - (1..1).toList().map { TestObjectHelpers.apiSkillUpdateGenerator() }, "testReindexAll" + (1..1).toList().map { TestObjectHelpers.apiSkillUpdateGenerator() }, "testReindexAll", "testReindexAll" ) // Act diff --git a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt index 619fae3dd..a9c5b6ec0 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt @@ -133,7 +133,11 @@ class RichSkillRepositoryTest @Autowired constructor( @Test fun `should update an existing skill from an ApiSkillUpdate object`() { val originalSkillUpdate = apiSkillUpdateGenerator() - val originalSkillDao = richSkillRepository.createFromApi(listOf(originalSkillUpdate), userString).first() + val originalSkillDao = richSkillRepository.createFromApi( + listOf(originalSkillUpdate), + userString, + task.userEmail + ).first() var newSkillUpdate = apiSkillUpdateGenerator() newSkillUpdate = newSkillUpdate.copy( @@ -146,7 +150,12 @@ class RichSkillRepositoryTest @Autowired constructor( collections=newSkillUpdate.collections?.copy(remove=originalSkillUpdate.collections?.add) ) - val updatedDao = richSkillRepository.updateFromApi(originalSkillDao.id.value, newSkillUpdate, userString) + val updatedDao = richSkillRepository.updateFromApi( + originalSkillDao.id.value, + newSkillUpdate, + userString, + oAuthHelper.readableEmail(user) + ) assertThat(updatedDao).isNotNull assertThatRichSkillMatchesApiSkillUpdate(RichSkillAndCollections.fromDao(updatedDao!!), newSkillUpdate) } @@ -156,7 +165,11 @@ class RichSkillRepositoryTest @Autowired constructor( val skillCount = 1 val skillUpdates = (1..skillCount).toList().map { apiSkillUpdateGenerator() } - val results: List = richSkillRepository.createFromApi(skillUpdates, userString) + val results: List = richSkillRepository.createFromApi( + skillUpdates, + userString, + task.userEmail + ) results.forEachIndexed { i, skillDao -> val skillAndCollections = RichSkillAndCollections.fromDao(skillDao) @@ -264,7 +277,12 @@ class RichSkillRepositoryTest @Autowired constructor( val apiUpdate = ApiSkillUpdate( skillName=newName ) - var apiUpdated = richSkillRepository.updateFromApi(created!!.id!!, apiUpdate, userString)?.toModel() + var apiUpdated = richSkillRepository.updateFromApi( + created!!.id!!, + apiUpdate, + userString, + oAuthHelper.readableEmail(user) + )?.toModel() assertThat(apiUpdated).isNotNull assertThat(apiUpdated?.category?.value).isEqualTo(categoryName) @@ -272,7 +290,12 @@ class RichSkillRepositoryTest @Autowired constructor( val apiUpdateBlank = ApiSkillUpdate( category="" ) - apiUpdated = richSkillRepository.updateFromApi(created.id!!, apiUpdateBlank, userString)?.toModel() + apiUpdated = richSkillRepository.updateFromApi( + created.id!!, + apiUpdateBlank, + userString, + oAuthHelper.readableEmail(user) + )?.toModel() assertThat(apiUpdated).isNotNull assertThat(apiUpdated?.category).isNull() } @@ -287,8 +310,8 @@ class RichSkillRepositoryTest @Autowired constructor( name="${searchQuery} ${UUID.randomUUID()}" )} - val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString) - val knownDaos = richSkillRepository.createFromApi(knownUpdates, userString) + val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString, task.userEmail) + val knownDaos = richSkillRepository.createFromApi(knownUpdates, userString, task.userEmail) assertThat(skillDaos.size + knownDaos.size).isEqualTo(totalSkillCount) val batchResult = richSkillRepository.changeStatusesForTask(PublishTask( @@ -323,26 +346,46 @@ class RichSkillRepositoryTest @Autowired constructor( val notIncludedCount = 10 val archivedSkills = (1..archivedCount).toList().flatMap { - richSkillRepository.createFromApi(listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Published)), userString).map { skillDao -> + richSkillRepository.createFromApi( + listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Published)), + userString, + task.userEmail + ).map { skillDao -> richSkillRepository.update(RsdUpdateObject(id=skillDao.id.value, publishStatus=PublishStatus.Archived), userString) }.filterNotNull() } val publishedSkills = (1..publishedCount).toList().flatMap { - richSkillRepository.createFromApi(listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Published)), userString) + richSkillRepository.createFromApi( + listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Published)), + userString, + task.userEmail + ) } val draftSkills = (1..draftCount).toList().flatMap { - richSkillRepository.createFromApi(listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), userString) + richSkillRepository.createFromApi( + listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), + userString, + task.userEmail + ) } // make skills that are draft+archived val deletedSkills = (1..deletedCount).toList().flatMap { - richSkillRepository.createFromApi(listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), userString).map { skillDao -> + richSkillRepository.createFromApi( + listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), + userString, + task.userEmail + ).map { skillDao -> richSkillRepository.update(RsdUpdateObject(id=skillDao.id.value, publishStatus=PublishStatus.Archived), userString) }.filterNotNull() } val extraSkills = (1..notIncludedCount).toList().flatMap { - richSkillRepository.createFromApi(listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), userString) + richSkillRepository.createFromApi( + listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), + userString, + task.userEmail + ) } publishedSkills.forEach { assertThat(it.publishStatus()).isEqualTo(PublishStatus.Published) } @@ -379,7 +422,7 @@ class RichSkillRepositoryTest @Autowired constructor( fun `should be able to bulk publish or archive skills based on uuids`() { val totalSkillCount = 10 val skillUpdates = (1..totalSkillCount).toList().map { apiSkillUpdateGenerator() } - val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString) + val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString, task.userEmail) assertThat(skillDaos.size).isEqualTo(totalSkillCount) val toPublishCount = 3 @@ -425,8 +468,8 @@ class RichSkillRepositoryTest @Autowired constructor( val skillUpdate = apiSkillUpdateGenerator().copy(occupations = ApiStringListUpdate(add = listOf(jobCode.code))) val noiseSkillCount = 10 val noiseSkillUpdates = (1..noiseSkillCount).toList().map { apiSkillUpdateGenerator() } - richSkillRepository.createFromApi(noiseSkillUpdates, userString) - val skillDao = richSkillRepository.createFromApi(listOf(skillUpdate), userString).first() + richSkillRepository.createFromApi(noiseSkillUpdates, userString, task.userEmail) + val skillDao = richSkillRepository.createFromApi(listOf(skillUpdate), userString, task.userEmail).first() val result = richSkillRepository.containingJobCode(jobCode.code) assertThat(result.first().uuid).isEqualTo(skillDao.uuid) From c5b7f34cc7b519b7f5193d77534253d54743e10f Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Feb 2023 15:14:17 -0600 Subject: [PATCH 017/150] Start fixing unit testing --- .../test/kotlin/edu/wgu/osmt/SpringTest.kt | 2 + .../kotlin/edu/wgu/osmt/TestObjectHelpers.kt | 11 ++++- .../osmt/auditlog/AuditLogRepositoryTest.kt | 14 ++++-- .../kotlin/edu/wgu/osmt/mockdata/MockData.kt | 11 +++-- .../edu/wgu/osmt/mockdata/xml/Collection.kt | 1 + .../osmt/richskill/RichSkillRepositoryTest.kt | 46 +++++++++++-------- api/src/test/resources/mock-data.xml | 14 +++--- 7 files changed, 64 insertions(+), 35 deletions(-) diff --git a/api/src/test/kotlin/edu/wgu/osmt/SpringTest.kt b/api/src/test/kotlin/edu/wgu/osmt/SpringTest.kt index 14edda3d6..cb536595c 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/SpringTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/SpringTest.kt @@ -35,6 +35,8 @@ abstract class SpringTest: BaseDockerizedTest { val testUser = "test-user" + val testEmail = "test@email.com" + init { logger.info("Mysql port ${Containers.mysqlContainer.getMappedPort(3306)}") logger.info("Redis port ${Containers.redisContainer.getMappedPort(6379)}") diff --git a/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt b/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt index 2b5f0668b..5097ce72b 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt @@ -1,6 +1,11 @@ package edu.wgu.osmt -import edu.wgu.osmt.api.model.* +import edu.wgu.osmt.api.model.ApiAlignment +import edu.wgu.osmt.api.model.ApiAlignmentListUpdate +import edu.wgu.osmt.api.model.ApiNamedReference +import edu.wgu.osmt.api.model.ApiReferenceListUpdate +import edu.wgu.osmt.api.model.ApiSkillUpdate +import edu.wgu.osmt.api.model.ApiStringListUpdate import edu.wgu.osmt.collection.CollectionDoc import edu.wgu.osmt.db.PublishStatus import edu.wgu.osmt.jobcode.JobCode @@ -38,7 +43,9 @@ object TestObjectHelpers { publishStatus = publishStatus, skillIds = skillIds, skillCount = skillIds.count(), - author = author ?: authorString + "-collection" + author = author ?: authorString + "-collection", + workspaceOwner = "owner@email.com", + status = PublishStatus.Draft ) fun randomString(): String = UUID.randomUUID().toString().replace("-", "") diff --git a/api/src/test/kotlin/edu/wgu/osmt/auditlog/AuditLogRepositoryTest.kt b/api/src/test/kotlin/edu/wgu/osmt/auditlog/AuditLogRepositoryTest.kt index a07ddc423..cb57dd77b 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/auditlog/AuditLogRepositoryTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/auditlog/AuditLogRepositoryTest.kt @@ -14,7 +14,11 @@ import edu.wgu.osmt.db.PublishStatus import edu.wgu.osmt.jobcode.JobCodeRepository import edu.wgu.osmt.keyword.KeywordRepository import edu.wgu.osmt.keyword.KeywordTypeEnum -import edu.wgu.osmt.richskill.* +import edu.wgu.osmt.richskill.RichSkillDescriptor +import edu.wgu.osmt.richskill.RichSkillDescriptorDao +import edu.wgu.osmt.richskill.RichSkillDescriptorTable +import edu.wgu.osmt.richskill.RichSkillRepository +import edu.wgu.osmt.richskill.RsdUpdateObject import org.assertj.core.api.Assertions.assertThat import org.jetbrains.exposed.sql.SizedIterable import org.junit.jupiter.api.Test @@ -57,7 +61,7 @@ class AuditLogRepositoryTest @Autowired constructor( @Test fun `generates an audit log on collection creation`() { - val collectionDao = collectionRepository.create("test collection", testUser) + val collectionDao = collectionRepository.create("test collection", testUser, testEmail) val auditLog = collectionDao?.id?.value?.let { auditLogRepository.findByTableAndId(CollectionTable.tableName, it) }?.first() @@ -87,7 +91,7 @@ class AuditLogRepositoryTest @Autowired constructor( val initialCollectionUpdate = CollectionUpdateObject(name = "test collection", skills = ListFieldUpdate(add = listOf(initialSkill!!))) - val collectionDao = collectionRepository.create(initialCollectionUpdate, testUser) + val collectionDao = collectionRepository.create(initialCollectionUpdate, testUser, testEmail) val newAuthorDao = keywordRepository.create(KeywordTypeEnum.Author, updatedAuthorName) val collectionUpdateObject = CollectionUpdateObject( @@ -170,7 +174,7 @@ class AuditLogRepositoryTest @Autowired constructor( val keywordDaos = TestObjectHelpers.keywordsGenerator(10, KeywordTypeEnum.Keyword) .mapNotNull { keywordRepository.create(it.type, it.value) } val jobCodeDaos = listOf(jobCodeRepository.create("11-1170")) - val collectionDaos = listOf(collectionRepository.create("test collection", testUser)!!) + val collectionDaos = listOf(collectionRepository.create("test collection", testUser, testEmail)!!) val newName = "updated skill" val newStatement = "new statement" @@ -327,7 +331,7 @@ class AuditLogRepositoryTest @Autowired constructor( CollectionUpdateObject(name = initialCollectionName, skills = ListFieldUpdate(add = listOf(initialSkill!!))) // Act - val collectionDao = collectionRepository.create(initialCollectionUpdate, testUser) + val collectionDao = collectionRepository.create(initialCollectionUpdate, testUser, testEmail) val collectionUpdate = CollectionUpdateObject(id = collectionDao?.id?.value, name = updatedCollectionName) collectionRepository.update(collectionUpdate, testUser) diff --git a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt index d37d40df9..fd41d9734 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt @@ -302,7 +302,9 @@ class MockData { c.skillsCount, lookupKeywordValue(c.author?.toLong()), parseDateTime(c.archiveDate), - parseDateTime(c.publishDate) + parseDateTime(c.publishDate), + c.workspaceOwner!!, + PublishStatus.valueOf(c.status!!) ) } } @@ -379,7 +381,8 @@ class MockData { name = doc.name, author = lookupKeywordByValue(doc.author), archiveDate = doc.archiveDate, - publishDate = doc.publishDate + publishDate = doc.publishDate, + status = doc.status ) } @@ -393,7 +396,9 @@ class MockData { publishDate = c.publishDate, publishStatus = c.publishStatus(), skillCount = 0, - skillIds = null + skillIds = null, + status = c.status, + workspaceOwner = c.workspaceOwner ) } diff --git a/api/src/test/kotlin/edu/wgu/osmt/mockdata/xml/Collection.kt b/api/src/test/kotlin/edu/wgu/osmt/mockdata/xml/Collection.kt index fd33f048d..e3fa674f9 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/mockdata/xml/Collection.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/mockdata/xml/Collection.kt @@ -10,4 +10,5 @@ class Collection { var author: String? = null var archiveDate: String? = null var publishDate: String? = null + var workspaceOwner: String? = null } \ No newline at end of file diff --git a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt index a9c5b6ec0..6ab423b94 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillRepositoryTest.kt @@ -1,10 +1,18 @@ package edu.wgu.osmt.richskill -import edu.wgu.osmt.* +import edu.wgu.osmt.BaseDockerizedTest +import edu.wgu.osmt.HasDatabaseReset +import edu.wgu.osmt.HasElasticsearchReset +import edu.wgu.osmt.SpringTest +import edu.wgu.osmt.TestObjectHelpers import edu.wgu.osmt.TestObjectHelpers.apiSkillUpdateGenerator import edu.wgu.osmt.TestObjectHelpers.assertThatKeywordMatchesAlignment import edu.wgu.osmt.TestObjectHelpers.assertThatKeywordMatchesNamedReference -import edu.wgu.osmt.api.model.* +import edu.wgu.osmt.api.model.ApiAlignmentListUpdate +import edu.wgu.osmt.api.model.ApiReferenceListUpdate +import edu.wgu.osmt.api.model.ApiSearch +import edu.wgu.osmt.api.model.ApiSkillUpdate +import edu.wgu.osmt.api.model.ApiStringListUpdate import edu.wgu.osmt.collection.Collection import edu.wgu.osmt.collection.CollectionEsRepo import edu.wgu.osmt.collection.CollectionRepository @@ -43,6 +51,8 @@ class RichSkillRepositoryTest @Autowired constructor( lateinit var keywordRepository: KeywordRepository val userString = "unittestuser" + + val userEmail = "user@email.com" fun assertThatKeywordsMatchStringList(keywords: List, stringList: ApiStringListUpdate) { @@ -136,7 +146,7 @@ class RichSkillRepositoryTest @Autowired constructor( val originalSkillDao = richSkillRepository.createFromApi( listOf(originalSkillUpdate), userString, - task.userEmail + userEmail ).first() var newSkillUpdate = apiSkillUpdateGenerator() @@ -154,7 +164,7 @@ class RichSkillRepositoryTest @Autowired constructor( originalSkillDao.id.value, newSkillUpdate, userString, - oAuthHelper.readableEmail(user) + userEmail ) assertThat(updatedDao).isNotNull assertThatRichSkillMatchesApiSkillUpdate(RichSkillAndCollections.fromDao(updatedDao!!), newSkillUpdate) @@ -168,7 +178,7 @@ class RichSkillRepositoryTest @Autowired constructor( val results: List = richSkillRepository.createFromApi( skillUpdates, userString, - task.userEmail + userEmail ) results.forEachIndexed { i, skillDao -> @@ -281,7 +291,7 @@ class RichSkillRepositoryTest @Autowired constructor( created!!.id!!, apiUpdate, userString, - oAuthHelper.readableEmail(user) + userEmail )?.toModel() assertThat(apiUpdated).isNotNull assertThat(apiUpdated?.category?.value).isEqualTo(categoryName) @@ -294,7 +304,7 @@ class RichSkillRepositoryTest @Autowired constructor( created.id!!, apiUpdateBlank, userString, - oAuthHelper.readableEmail(user) + userEmail )?.toModel() assertThat(apiUpdated).isNotNull assertThat(apiUpdated?.category).isNull() @@ -310,8 +320,8 @@ class RichSkillRepositoryTest @Autowired constructor( name="${searchQuery} ${UUID.randomUUID()}" )} - val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString, task.userEmail) - val knownDaos = richSkillRepository.createFromApi(knownUpdates, userString, task.userEmail) + val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString, userEmail) + val knownDaos = richSkillRepository.createFromApi(knownUpdates, userString, userEmail) assertThat(skillDaos.size + knownDaos.size).isEqualTo(totalSkillCount) val batchResult = richSkillRepository.changeStatusesForTask(PublishTask( @@ -349,7 +359,7 @@ class RichSkillRepositoryTest @Autowired constructor( richSkillRepository.createFromApi( listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Published)), userString, - task.userEmail + userEmail ).map { skillDao -> richSkillRepository.update(RsdUpdateObject(id=skillDao.id.value, publishStatus=PublishStatus.Archived), userString) }.filterNotNull() @@ -358,14 +368,14 @@ class RichSkillRepositoryTest @Autowired constructor( richSkillRepository.createFromApi( listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Published)), userString, - task.userEmail + userEmail ) } val draftSkills = (1..draftCount).toList().flatMap { richSkillRepository.createFromApi( listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), userString, - task.userEmail + userEmail ) } @@ -374,7 +384,7 @@ class RichSkillRepositoryTest @Autowired constructor( richSkillRepository.createFromApi( listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), userString, - task.userEmail + userEmail ).map { skillDao -> richSkillRepository.update(RsdUpdateObject(id=skillDao.id.value, publishStatus=PublishStatus.Archived), userString) }.filterNotNull() @@ -384,7 +394,7 @@ class RichSkillRepositoryTest @Autowired constructor( richSkillRepository.createFromApi( listOf(apiSkillUpdateGenerator(publishStatus=PublishStatus.Draft)), userString, - task.userEmail + userEmail ) } @@ -394,7 +404,7 @@ class RichSkillRepositoryTest @Autowired constructor( deletedSkills.forEach { assertThat(it.publishStatus()).isEqualTo(PublishStatus.Deleted) } // create collection - val collectionDao = collectionRepository.create(UUID.randomUUID().toString(), userString) + val collectionDao = collectionRepository.create(UUID.randomUUID().toString(), userString, userEmail) val collection = collectionDao?.toModel() assertThat(collection).isNotNull @@ -422,7 +432,7 @@ class RichSkillRepositoryTest @Autowired constructor( fun `should be able to bulk publish or archive skills based on uuids`() { val totalSkillCount = 10 val skillUpdates = (1..totalSkillCount).toList().map { apiSkillUpdateGenerator() } - val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString, task.userEmail) + val skillDaos = richSkillRepository.createFromApi(skillUpdates, userString, userEmail) assertThat(skillDaos.size).isEqualTo(totalSkillCount) val toPublishCount = 3 @@ -468,8 +478,8 @@ class RichSkillRepositoryTest @Autowired constructor( val skillUpdate = apiSkillUpdateGenerator().copy(occupations = ApiStringListUpdate(add = listOf(jobCode.code))) val noiseSkillCount = 10 val noiseSkillUpdates = (1..noiseSkillCount).toList().map { apiSkillUpdateGenerator() } - richSkillRepository.createFromApi(noiseSkillUpdates, userString, task.userEmail) - val skillDao = richSkillRepository.createFromApi(listOf(skillUpdate), userString, task.userEmail).first() + richSkillRepository.createFromApi(noiseSkillUpdates, userString, userEmail) + val skillDao = richSkillRepository.createFromApi(listOf(skillUpdate), userString, userEmail).first() val result = richSkillRepository.containingJobCode(jobCode.code) assertThat(result.first().uuid).isEqualTo(skillDao.uuid) diff --git a/api/src/test/resources/mock-data.xml b/api/src/test/resources/mock-data.xml index 76fc4221a..8eaa862f5 100644 --- a/api/src/test/resources/mock-data.xml +++ b/api/src/test/resources/mock-data.xml @@ -632,13 +632,13 @@ 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 - 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778 - 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 - 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 - 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 - 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 - 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538 - 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548 + 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778user@email.com + 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378user@email.com + 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078user@email.com + 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778user@email.com + 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688user@email.com + 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538user@email.com + 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548user@email.com 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 From a290db436613fb04271763503480d340acd494f2 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Feb 2023 16:07:41 -0600 Subject: [PATCH 018/150] Fixing unit testing --- .../kotlin/edu/wgu/osmt/collection/CollectionDao.kt | 1 - .../kotlin/edu/wgu/osmt/collection/CollectionDoc.kt | 5 +---- api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt | 10 ++-------- api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt | 3 +-- api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt | 6 ++---- 5 files changed, 6 insertions(+), 19 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt index f6d7b2240..b1c3c7523 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionDao.kt @@ -46,7 +46,6 @@ class CollectionDao(id: EntityID) : LongEntity(id), OutputsModel + val workspaceOwner: String? ) diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt b/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt index 75658e0e0..18a81f590 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/db/PublishStatus.kt @@ -1,6 +1,6 @@ package edu.wgu.osmt.db -import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonValue const val UNARCHIVED = "unarchived" const val DELETED = "deleted" @@ -9,18 +9,12 @@ const val PUBLISHED = "published" const val ARCHIVED = "archived" const val DRAFT = "draft" -enum class PublishStatus(val apiValue: String) { - @JsonProperty("unarchived") +enum class PublishStatus(@JsonValue val apiValue: String) { Unarchived(UNARCHIVED), - @JsonProperty("deleted") Deleted(DELETED), - @JsonProperty("workspace") Workspace(WORKSPACE), - @JsonProperty("published") Published(PUBLISHED), - @JsonProperty("archived") Archived(ARCHIVED), - @JsonProperty("draft") Draft(DRAFT); companion object { diff --git a/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt b/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt index 5097ce72b..6112c1398 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/TestObjectHelpers.kt @@ -44,8 +44,7 @@ object TestObjectHelpers { skillIds = skillIds, skillCount = skillIds.count(), author = author ?: authorString + "-collection", - workspaceOwner = "owner@email.com", - status = PublishStatus.Draft + workspaceOwner = "owner@email.com" ) fun randomString(): String = UUID.randomUUID().toString().replace("-", "") diff --git a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt index fd41d9734..59083c24d 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt @@ -303,8 +303,7 @@ class MockData { lookupKeywordValue(c.author?.toLong()), parseDateTime(c.archiveDate), parseDateTime(c.publishDate), - c.workspaceOwner!!, - PublishStatus.valueOf(c.status!!) + c.workspaceOwner!! ) } } @@ -382,7 +381,7 @@ class MockData { author = lookupKeywordByValue(doc.author), archiveDate = doc.archiveDate, publishDate = doc.publishDate, - status = doc.status + status = doc.publishStatus ) } @@ -397,7 +396,6 @@ class MockData { publishStatus = c.publishStatus(), skillCount = 0, skillIds = null, - status = c.status, workspaceOwner = c.workspaceOwner ) } From a84461be02fc4db7dd47aa95b9c0ff33229fd069 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Feb 2023 18:14:59 -0600 Subject: [PATCH 019/150] Fixing Enum mapping --- api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt | 2 +- api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt index feda18de3..a7e102330 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt @@ -21,7 +21,7 @@ data class Collection( val name: String, val author: Keyword? = null, val workspaceOwner: String? = null, - val status: Enum, + val status: PublishStatus, override val archiveDate: LocalDateTime? = null, override val publishDate: LocalDateTime? = null ) : DatabaseData, HasUpdateDate, PublishStatusDetails { diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt index e3c7f96ee..1140b8c62 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionTable.kt @@ -32,7 +32,7 @@ object CollectionTable: TableWithUpdate, PublishStatusUp val workspaceOwner = varchar("workspace_owner", 64).index().default("") val status = customEnumeration( "status", - fromDb = { value -> PublishStatus.valueOf(value as String) }, toDb = { it.name }).default(PublishStatus.Draft) + fromDb = { value -> PublishStatus.forApiValue(value as String)!! }, toDb = { it.name }).default(PublishStatus.Draft) } object CollectionSkills : Table("CollectionSkills") { From 28c9ea068c7d5246a75507dd6686a0af1b2901e0 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 2 Feb 2023 08:54:25 -0600 Subject: [PATCH 020/150] Adding workspace endpoint to be retrieved. --- api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt | 1 + .../edu/wgu/osmt/collection/CollectionController.kt | 10 ++++++++++ .../edu/wgu/osmt/collection/CollectionRepository.kt | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt b/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt index 8ccc01009..bc03a1cd4 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt @@ -32,6 +32,7 @@ object RoutePaths { const val COLLECTION_CSV = "$COLLECTION_DETAIL/csv" const val COLLECTION_REMOVE = "$COLLECTION_DETAIL/remove" + const val WORKSPACE_PATH = "$API/workspace" const val TASKS_PATH = "$API/results" const val TASK_DETAIL_TEXT = "$TASKS_PATH/text/{uuid}" diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt index 6affaabf5..b4debe184 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt @@ -203,4 +203,14 @@ class CollectionController @Autowired constructor( val sizedIterable = auditLogRepository.findByTableAndId(CollectionTable.tableName, entityId = collection!!.id.value, offsetPageable = pageable) return ResponseEntity.status(200).body(sizedIterable.toList().map{it.toModel()}) } + + @GetMapping(RoutePaths.WORKSPACE_PATH, produces = [MediaType.APPLICATION_JSON_VALUE]) + @ResponseBody + fun workspaceByOwner( + @AuthenticationPrincipal user: Jwt? + ): ApiCollection? { + return collectionRepository.findByOwner(oAuthHelper.readableEmail(user))?.let { + ApiCollection.fromDao(it, appConfig) + } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) + } } diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt index 766d7fe1c..e909245cd 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt @@ -48,6 +48,7 @@ interface CollectionRepository { fun create(updateObject: CollectionUpdateObject, user: String, email: String): CollectionDao? fun update(updateObject: CollectionUpdateObject, user: String): CollectionDao? fun remove(uuid: String): ApiBatchResult + fun findByOwner(owner: String) : CollectionDao? fun createFromApi( apiUpdates: List, @@ -240,6 +241,11 @@ class CollectionRepositoryImpl @Autowired constructor( } + override fun findByOwner(owner: String): CollectionDao? { + val query = table.select { table.workspaceOwner eq owner }.firstOrNull() + return query?.let { dao.wrapRow(it) } + } + override fun createFromApi( apiUpdates: List, richSkillRepository: RichSkillRepository, From 33820d8d5891faa1679c77b79f9944d2527163a0 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 2 Feb 2023 09:32:24 -0600 Subject: [PATCH 021/150] removing whitespaces, refactoring getter --- .../kotlin/edu/wgu/osmt/api/model/ApiCollection.kt | 2 +- .../edu/wgu/osmt/collection/CollectionController.kt | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt index 3af618fba..06604f4b0 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt @@ -65,7 +65,7 @@ class ApiCollection(private val collection: Collection, private val ss: List { return collectionRepository.createFromApi( apiCollectionUpdates, - richSkillRepository, oAuthHelper.readableUsername(user), oAuthHelper.readableEmail(user) + richSkillRepository, + oAuthHelper.readableUsername(user), + oAuthHelper.readableEmail(user) ).map { ApiCollection.fromDao(it, appConfig) } @@ -186,7 +188,6 @@ class CollectionController @Autowired constructor( fun removeCollection( @PathVariable uuid: String ): HttpEntity { - val task = RemoveCollectionSkillsTask(collectionUuid = uuid) taskMessageService.enqueueJob(TaskMessageService.removeCollectionSkills, task) return Task.processingResponse(task) @@ -209,8 +210,10 @@ class CollectionController @Autowired constructor( fun workspaceByOwner( @AuthenticationPrincipal user: Jwt? ): ApiCollection? { - return collectionRepository.findByOwner(oAuthHelper.readableEmail(user))?.let { - ApiCollection.fromDao(it, appConfig) + return collectionRepository.findByOwner( + oAuthHelper.readableEmail(user))?.let { + ApiCollection.fromDao(it, appConfig + ) } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) } } From 238313351f44dd9996f946552e88060e4d2675ac Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 2 Feb 2023 10:13:10 -0600 Subject: [PATCH 022/150] refactoring WS endpoint to retrieve the default one per user o create a new one if it does not exist --- .../wgu/osmt/collection/CollectionController.kt | 14 +++++++++++++- .../test/kotlin/edu/wgu/osmt/mockdata/MockData.kt | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt index 2446b908d..52ff468da 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt @@ -214,6 +214,18 @@ class CollectionController @Autowired constructor( oAuthHelper.readableEmail(user))?.let { ApiCollection.fromDao(it, appConfig ) - } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) + } ?: collectionRepository.createFromApi( + listOf( + ApiCollectionUpdate( + "defaultWorkspace", + PublishStatus.Workspace, + oAuthHelper.readableUsername(user), + null + ) + ), + richSkillRepository, + oAuthHelper.readableUsername(user), + oAuthHelper.readableEmail(user) + ).firstOrNull()?.let { ApiCollection.fromDao(it, appConfig) } } } diff --git a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt index 59083c24d..1bb9bb40e 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt @@ -297,7 +297,7 @@ class MockData { c.id!!, c.uuid!!, c.name!!, - PublishStatus.valueOf(c.status!!), + c.status?.let { PublishStatus.forApiValue(it) }!!, skillUUIDs as List, c.skillsCount, lookupKeywordValue(c.author?.toLong()), From 7ddabc6320b3eab7c18463e5451b27e0bbd6a155 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 2 Feb 2023 10:27:13 -0600 Subject: [PATCH 023/150] refactoring null --- .../kotlin/edu/wgu/osmt/collection/CollectionController.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt index 52ff468da..240c8b222 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt @@ -7,6 +7,7 @@ import edu.wgu.osmt.api.model.ApiCollection import edu.wgu.osmt.api.model.ApiCollectionUpdate import edu.wgu.osmt.api.model.ApiSearch import edu.wgu.osmt.api.model.ApiSkillListUpdate +import edu.wgu.osmt.api.model.ApiStringListUpdate import edu.wgu.osmt.api.model.CollectionSortEnum import edu.wgu.osmt.auditlog.AuditLog import edu.wgu.osmt.auditlog.AuditLogRepository @@ -220,7 +221,7 @@ class CollectionController @Autowired constructor( "defaultWorkspace", PublishStatus.Workspace, oAuthHelper.readableUsername(user), - null + ApiStringListUpdate() ) ), richSkillRepository, From 0debcb671785a32f9732f4702dd540ad27b04521 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 31 Jan 2023 14:11:32 -0600 Subject: [PATCH 024/150] Simulated workspace --- ui/src/app/auth/auth-service.ts | 6 ++ ui/src/app/collection/ApiCollection.ts | 9 ++- .../detail/manage-collection.component.ts | 5 -- .../my-workspace/my-workspace.component.ts | 55 ++++++++++++++++--- .../richskill/list/skills-list.component.ts | 2 +- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/ui/src/app/auth/auth-service.ts b/ui/src/app/auth/auth-service.ts index f850a570d..7d18d2075 100644 --- a/ui/src/app/auth/auth-service.ts +++ b/ui/src/app/auth/auth-service.ts @@ -9,6 +9,7 @@ import { IAuthService } from "./iauth-service" export const STORAGE_KEY_TOKEN = "OSMT.AuthService.accessToken" export const STORAGE_KEY_RETURN = "OSMT.AuthService.return" export const STORAGE_KEY_ROLE = "OSMT.AuthService.role" +export const STORAGE_KEY_EMAIL = "OSMT.AuthService.email" @Injectable() export class AuthService extends Whitelabelled implements IAuthService { @@ -36,6 +37,7 @@ export class AuthService extends Whitelabelled implements IAuthService { storeToken(accessToken: string): void { localStorage.setItem(STORAGE_KEY_TOKEN, accessToken) + localStorage.setItem(STORAGE_KEY_EMAIL, JSON.parse(atob(accessToken.split(".")[1]))?.email) localStorage.setItem(STORAGE_KEY_ROLE, JSON.parse(atob(accessToken.split(".")[1]))?.roles) } @@ -52,6 +54,10 @@ export class AuthService extends Whitelabelled implements IAuthService { return ret } + getEmail(): string | null { + return localStorage.getItem(STORAGE_KEY_EMAIL) + } + logout(): void { localStorage.removeItem(STORAGE_KEY_TOKEN) } diff --git a/ui/src/app/collection/ApiCollection.ts b/ui/src/app/collection/ApiCollection.ts index 930aa4003..34b4c60b9 100644 --- a/ui/src/app/collection/ApiCollection.ts +++ b/ui/src/app/collection/ApiCollection.ts @@ -8,6 +8,7 @@ export interface ICollection { creator: string id: string name: string + workspaceOwner?: string publishDate?: Date skills: string[] status: PublishStatus @@ -23,6 +24,7 @@ export class ApiCollection { id: string name: string publishDate?: Date + workspaceOwner?: string skills: string[] status: PublishStatus updateDate?: Date @@ -36,6 +38,7 @@ export class ApiCollection { creator, id, name, + workspaceOwner, publishDate, skills, status, @@ -49,6 +52,7 @@ export class ApiCollection { this.creator = creator this.id = id this.name = name + this.workspaceOwner = workspaceOwner this.publishDate = publishDate this.skills = skills this.status = status @@ -62,6 +66,7 @@ export interface ICollectionUpdate { status?: PublishStatus, author?: string, skills?: IStringListUpdate + workspaceOwner?: string } export class ApiCollectionUpdate { @@ -69,11 +74,13 @@ export class ApiCollectionUpdate { status?: PublishStatus author?: string skills?: IStringListUpdate + workSpaceOwner?: string - constructor({name, status, author, skills}: ICollectionUpdate) { + constructor({name, status, author, skills, workspaceOwner}: ICollectionUpdate) { this.name = name this.status = status this.author = author this.skills = skills + this.workSpaceOwner = workspaceOwner } } diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index 754f5b040..cb8e7de59 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -275,11 +275,6 @@ export class ManageCollectionComponent extends SkillsListComponent implements On window.open(url, "_blank") } - conertToCollectionAction(): void { - - } - - publishAction(): void { if (this.uuidParam === undefined) { return } diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 1a3b29a41..df65e8ef6 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -7,9 +7,9 @@ import {ActivatedRoute, Router} from "@angular/router" import {Title} from "@angular/platform-browser" import {AuthService} from "../auth/auth-service" import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions" -import {ButtonAction} from "../auth/auth-roles" import {PublishStatus} from "../PublishStatus" -import {size} from "lodash" +import {ApiSearch} from "../richskill/service/rich-skill-search.service" +import {ApiCollectionUpdate} from "../collection/ApiCollection" @Component({ selector: "app-my-workspace", @@ -28,7 +28,6 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O @Inject(LOCALE_ID) protected locale: string ) { super(router, richSkillService, toastService, collectionService, route, titleService, authService, locale) - this.uuidParam = "00ff748a-7141-47f2-aaf5-f9b8a992505f" } ngOnInit(): void { @@ -36,10 +35,24 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O this.reloadCollection() } + reloadCollection(): void { + const uuid = localStorage.getItem("uuid") + if (uuid) { + this.collectionService.getCollectionByUUID(uuid).subscribe(collection => { + this.titleService.setTitle(`${collection.name} | Collection | ${this.whitelabel.toolName}`) + this.collection = collection + this.uuidParam = this.collection.uuid + localStorage.setItem("uuid", this.collection.uuid) + this.loadNextPage() + }, () => this.createWorkSpace()) + } else { + this.createWorkSpace() + } + } + actionDefinitions(): TableActionDefinition[] { this.collection ? this.collection.status = PublishStatus.Workspace : false - console.log(this.collection) - const actions = [ + return [ new TableActionDefinition({ label: "Add RSDs to My Workspace", icon: this.addIcon, @@ -55,17 +68,43 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O new TableActionDefinition({ label: "Convert to Collection", icon: this.publishIcon, - callback: () => this.conertToCollectionAction(), + callback: () => this.convertToCollectionAction(), visible: () => true }), new TableActionDefinition({ label: "Reset Collection", icon: this.deleteIcon, callback: () => this.deleteCollectionAction(), - visible: () => true + visible: () => (this.collection?.skills?.length ?? 0) > 0 }) ] - return actions + } + + private createWorkSpace(): void { + console.log("create workspace") + this.collectionService.createCollection({ + name: "My Workspace", + // workspaceOwner: this.authService.getEmail() ?? "", + // status: PublishStatus.Workspace + }).subscribe(collection => { + console.log(collection) + this.collection = collection + this.uuidParam = this.collection.uuid + localStorage.setItem("uuid", collection.uuid) + }) + } + + handleConfirmDeleteCollection(): void { + this.submitSkillRemoval(new ApiSearch({uuids: this.collection?.skills.map(s => (s as any).uuid)})) + this.template = "default" + } + + private convertToCollectionAction(): void { + const updateObject = new ApiCollectionUpdate({status: PublishStatus.Draft}) + this.collectionService.updateCollection(this.uuidParam ?? "", updateObject).subscribe(() => { + this.router.navigate(["/collections/" + this.uuidParam + "/manage"]) + }) + // this.submitCollectionStatusChange(PublishStatus.Published, "published") } } diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index a58f2df0a..4bd0662b9 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -288,7 +288,7 @@ export class SkillsListComponent extends QuickLinksHelper { protected handleClickAddToWorkspace(): void { const skillListUpdate = new ApiSkillListUpdate({add: new ApiSearch({uuids: this.getSelectedSkills()?.map(i => i.uuid)})}) this.toastService.showBlockingLoader() - this.collectionService.updateSkillsWithResult("4fafd06d-7fd1-498c-90e7-e70021a0bfc0", skillListUpdate).subscribe(result => { + this.collectionService.updateSkillsWithResult(localStorage.getItem("uuid") ?? "", skillListUpdate).subscribe(result => { if (result) { const message = `You added ${result.modifiedCount} RSDs to the collection.` this.toastService.showToast("Success!", message) From 4ef37aef264ad9a7d9ecbbbcf8c449f116182da6 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Wed, 1 Feb 2023 16:53:00 -0600 Subject: [PATCH 025/150] Update my workspace tests --- .../my-workspace.component.spec.ts | 36 ++++++++++++++++++- ui/test/resource/mock-stubs.ts | 11 ++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index b62471fc8..5af5ffbda 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -11,6 +11,8 @@ import {Title} from "@angular/platform-browser" import {ToastService} from "../toast/toast.service" import {EnvironmentService} from "../core/environment.service" import {CollectionService} from "../collection/service/collection.service" +import {Router} from "@angular/router" +import {ManageCollectionComponent} from "../collection/detail/manage-collection.component" describe("MyWorkspaceComponent", () => { let component: MyWorkspaceComponent @@ -19,7 +21,12 @@ describe("MyWorkspaceComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ - RouterTestingModule, + RouterTestingModule.withRoutes([ + { + path: "collections/uuid1/manage", + component: ManageCollectionComponent + } + ]), HttpClientTestingModule, ], declarations: [MyWorkspaceComponent], @@ -33,6 +40,9 @@ describe("MyWorkspaceComponent", () => { {provide: AuthService, useClass: AuthServiceStub}, ] }).compileComponents() + + const appConfig = TestBed.inject(AppConfig) + AppConfig.settings = appConfig.defaultConfig() }) beforeEach(() => { @@ -49,4 +59,28 @@ describe("MyWorkspaceComponent", () => { expect(component.actionDefinitions().length).toEqual(4) }) + it("create workspace should call create collection", () => { + const collectionService = TestBed.inject(CollectionService) + const spy = spyOn(collectionService, "createCollection").and.callThrough() + component["createWorkSpace"]() + expect(spy).toHaveBeenCalled() + }) + + it("handle confirm delete collection", () => { + const spy = spyOn(component, "submitSkillRemoval").and.callThrough() + component.handleConfirmDeleteCollection() + expect(spy).toHaveBeenCalled() + expect(component.template).toEqual("default") + }) + + it("convert to collection action", () => { + const collectionService = TestBed.inject(CollectionService) + const router = TestBed.inject(Router) + const spy = spyOn(collectionService, "updateCollection").and.callThrough() + const spyNavigate = spyOn(router, "navigate").and.callThrough() + component["convertToCollectionAction"]() + expect(spy).toHaveBeenCalled() + expect(spyNavigate).toHaveBeenCalled() + }) + }) diff --git a/ui/test/resource/mock-stubs.ts b/ui/test/resource/mock-stubs.ts index 54a572b49..d9b932619 100644 --- a/ui/test/resource/mock-stubs.ts +++ b/ui/test/resource/mock-stubs.ts @@ -262,6 +262,17 @@ export class CollectionServiceStub { return of(createMockPaginatedCollections()) } + createCollection(updateObject: ICollectionUpdate): Observable { + const date = new Date("2020-06-25T14:58:46.313Z") + return of(new ApiCollection(createMockCollection( + date, + date, + date, + date, + PublishStatus.Draft + ))) + } + deleteCollectionWithResult(uuid: string): Observable { return of(apiTaskResultForDeleteCollection) } From 475775f161e5244d5a615c3abf5456ac1b463586 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 2 Feb 2023 10:13:16 -0600 Subject: [PATCH 026/150] Using end point get workspace --- ui/src/app/collection/ApiCollection.ts | 4 +-- .../collection/service/collection.service.ts | 9 ++++++ .../my-workspace.component.spec.ts | 7 ----- .../my-workspace/my-workspace.component.ts | 28 +++---------------- .../richskill/list/skills-list.component.ts | 15 +++++----- ui/test/resource/mock-stubs.ts | 4 +-- 6 files changed, 24 insertions(+), 43 deletions(-) diff --git a/ui/src/app/collection/ApiCollection.ts b/ui/src/app/collection/ApiCollection.ts index 34b4c60b9..270213e1e 100644 --- a/ui/src/app/collection/ApiCollection.ts +++ b/ui/src/app/collection/ApiCollection.ts @@ -66,7 +66,6 @@ export interface ICollectionUpdate { status?: PublishStatus, author?: string, skills?: IStringListUpdate - workspaceOwner?: string } export class ApiCollectionUpdate { @@ -76,11 +75,10 @@ export class ApiCollectionUpdate { skills?: IStringListUpdate workSpaceOwner?: string - constructor({name, status, author, skills, workspaceOwner}: ICollectionUpdate) { + constructor({name, status, author, skills}: ICollectionUpdate) { this.name = name this.status = status this.author = author this.skills = skills - this.workSpaceOwner = workspaceOwner } } diff --git a/ui/src/app/collection/service/collection.service.ts b/ui/src/app/collection/service/collection.service.ts index 677b413b5..b7a2de5e0 100644 --- a/ui/src/app/collection/service/collection.service.ts +++ b/ui/src/app/collection/service/collection.service.ts @@ -123,6 +123,15 @@ export class CollectionService extends AbstractService { )) } + getWorkspace(): Observable { + const errorMsg = `Could not find workspace` + return this.get({ + path: "api/workspace" + }) + .pipe(share()) + .pipe(map(({body}) => new ApiCollection(this.safeUnwrapBody(body, errorMsg)))) + } + createCollection(updateObject: ICollectionUpdate): Observable { const errorMsg = `Error creating collection` return this.post({ diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index 5af5ffbda..2425d03e7 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -59,13 +59,6 @@ describe("MyWorkspaceComponent", () => { expect(component.actionDefinitions().length).toEqual(4) }) - it("create workspace should call create collection", () => { - const collectionService = TestBed.inject(CollectionService) - const spy = spyOn(collectionService, "createCollection").and.callThrough() - component["createWorkSpace"]() - expect(spy).toHaveBeenCalled() - }) - it("handle confirm delete collection", () => { const spy = spyOn(component, "submitSkillRemoval").and.callThrough() component.handleConfirmDeleteCollection() diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index df65e8ef6..2d457d04c 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -36,18 +36,12 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O } reloadCollection(): void { - const uuid = localStorage.getItem("uuid") - if (uuid) { - this.collectionService.getCollectionByUUID(uuid).subscribe(collection => { + this.collectionService.getWorkspace().subscribe(collection => { this.titleService.setTitle(`${collection.name} | Collection | ${this.whitelabel.toolName}`) this.collection = collection this.uuidParam = this.collection.uuid - localStorage.setItem("uuid", this.collection.uuid) this.loadNextPage() - }, () => this.createWorkSpace()) - } else { - this.createWorkSpace() - } + }) } actionDefinitions(): TableActionDefinition[] { @@ -80,31 +74,17 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O ] } - private createWorkSpace(): void { - console.log("create workspace") - this.collectionService.createCollection({ - name: "My Workspace", - // workspaceOwner: this.authService.getEmail() ?? "", - // status: PublishStatus.Workspace - }).subscribe(collection => { - console.log(collection) - this.collection = collection - this.uuidParam = this.collection.uuid - localStorage.setItem("uuid", collection.uuid) - }) - } - handleConfirmDeleteCollection(): void { this.submitSkillRemoval(new ApiSearch({uuids: this.collection?.skills.map(s => (s as any).uuid)})) this.template = "default" } private convertToCollectionAction(): void { - const updateObject = new ApiCollectionUpdate({status: PublishStatus.Draft}) + // @ts-ignore + const updateObject = new ApiCollectionUpdate({status: PublishStatus.Draft.toLowerCase()}) this.collectionService.updateCollection(this.uuidParam ?? "", updateObject).subscribe(() => { this.router.navigate(["/collections/" + this.uuidParam + "/manage"]) }) - // this.submitCollectionStatusChange(PublishStatus.Published, "published") } } diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 4bd0662b9..c847ecbd3 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -288,13 +288,14 @@ export class SkillsListComponent extends QuickLinksHelper { protected handleClickAddToWorkspace(): void { const skillListUpdate = new ApiSkillListUpdate({add: new ApiSearch({uuids: this.getSelectedSkills()?.map(i => i.uuid)})}) this.toastService.showBlockingLoader() - this.collectionService.updateSkillsWithResult(localStorage.getItem("uuid") ?? "", skillListUpdate).subscribe(result => { - if (result) { - const message = `You added ${result.modifiedCount} RSDs to the collection.` - this.toastService.showToast("Success!", message) - this.toastService.hideBlockingLoader() - // this.return() - } + this.collectionService.getWorkspace().subscribe(workspace => { + this.collectionService.updateSkillsWithResult(workspace.uuid, skillListUpdate).subscribe(result => { + if (result) { + const message = `You added ${result.modifiedCount} RSDs to the workspace.` + this.toastService.showToast("Success!", message) + this.toastService.hideBlockingLoader() + } + }) }) } diff --git a/ui/test/resource/mock-stubs.ts b/ui/test/resource/mock-stubs.ts index d9b932619..0ca87081e 100644 --- a/ui/test/resource/mock-stubs.ts +++ b/ui/test/resource/mock-stubs.ts @@ -262,14 +262,14 @@ export class CollectionServiceStub { return of(createMockPaginatedCollections()) } - createCollection(updateObject: ICollectionUpdate): Observable { + getWorkspace(): Observable { const date = new Date("2020-06-25T14:58:46.313Z") return of(new ApiCollection(createMockCollection( date, date, date, date, - PublishStatus.Draft + PublishStatus.Workspace ))) } From 32861ce0ea153c3cc76ea020c827ed76199927f4 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 2 Feb 2023 12:18:03 -0600 Subject: [PATCH 027/150] Add test add to workspace --- .../app/my-workspace/my-workspace.component.spec.ts | 9 ++++++++- .../app/richskill/list/skills-list.component.spec.ts | 12 ++++++++++-- ui/src/app/richskill/list/skills-list.component.ts | 1 - 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index 2425d03e7..2ef44784b 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -17,6 +17,7 @@ import {ManageCollectionComponent} from "../collection/detail/manage-collection. describe("MyWorkspaceComponent", () => { let component: MyWorkspaceComponent let fixture: ComponentFixture + let collectionService: CollectionService beforeEach(async () => { await TestBed.configureTestingModule({ @@ -48,9 +49,16 @@ describe("MyWorkspaceComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(MyWorkspaceComponent) component = fixture.componentInstance + collectionService = TestBed.inject(CollectionService) fixture.detectChanges() }) + it("reload collection should call get workspace", () => { + const spy = spyOn(collectionService, "getWorkspace").and.callThrough() + component.reloadCollection() + expect(spy).toHaveBeenCalled() + }) + it("should create", () => { expect(component).toBeTruthy() }) @@ -67,7 +75,6 @@ describe("MyWorkspaceComponent", () => { }) it("convert to collection action", () => { - const collectionService = TestBed.inject(CollectionService) const router = TestBed.inject(Router) const spy = spyOn(collectionService, "updateCollection").and.callThrough() const spyNavigate = spyOn(router, "navigate").and.callThrough() diff --git a/ui/src/app/richskill/list/skills-list.component.spec.ts b/ui/src/app/richskill/list/skills-list.component.spec.ts index 1e4a7335b..1b35a8a80 100644 --- a/ui/src/app/richskill/list/skills-list.component.spec.ts +++ b/ui/src/app/richskill/list/skills-list.component.spec.ts @@ -4,7 +4,7 @@ import { Component, ElementRef, Type } from "@angular/core" import { async, ComponentFixture, TestBed } from "@angular/core/testing" import { RouterTestingModule } from "@angular/router/testing" import { createMockPaginatedSkills, createMockSkillSummary } from "../../../../test/resource/mock-data" -import {AuthServiceStub, RichSkillServiceStub} from "../../../../test/resource/mock-stubs" +import {AuthServiceStub, CollectionServiceStub, RichSkillServiceStub} from "../../../../test/resource/mock-stubs" import { PublishStatus } from "../../PublishStatus" import { ToastService } from "../../toast/toast.service" import { ApiSortOrder } from "../ApiSkill" @@ -67,7 +67,8 @@ describe("SkillsListComponent", () => { providers: [ ToastService, { provide: RichSkillService, useClass: RichSkillServiceStub }, - { provide: AuthService, useClass: AuthServiceStub } + { provide: AuthService, useClass: AuthServiceStub }, + { provide: CollectionService, useClass: CollectionServiceStub }, ] }) @@ -98,6 +99,13 @@ describe("SkillsListComponent", () => { expect(component.getSelectAllCount()).toEqual(component.curPageCount) }) + it("handle click add to workspace", () => { + const collectionService = TestBed.inject(CollectionService) + const spy = spyOn(collectionService, "getWorkspace").and.callThrough() + component["handleClickAddToWorkspace"]() + expect(spy).toHaveBeenCalled() + }) + it("skillCountLabel should be correct", () => { component.setResults(createMockPaginatedSkills(0, 0)) expect(component.skillCountLabel).toEqual("0 RSDs") diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index c847ecbd3..2b7b97253 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -300,7 +300,6 @@ export class SkillsListComponent extends QuickLinksHelper { } protected handleClickAddCollection(action: TableActionDefinition, skill?: ApiSkillSummary): boolean { - console.log("handleClickAddCollection") const selection = this.getSelectedSkills(skill) this.router.navigate(["/collections/add-skills"], { state: { From 4b0defc1fd508e07866fc433526c4fb0dd1d6dea Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 2 Feb 2023 12:24:15 -0600 Subject: [PATCH 028/150] clearing owner field after changing status of a workspace --- api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt b/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt index 8325c0b25..717f7f0ac 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt @@ -1,6 +1,7 @@ package edu.wgu.osmt.db import edu.wgu.osmt.collection.CollectionDao +import org.apache.commons.lang3.StringUtils import org.jetbrains.exposed.dao.LongEntity import java.time.LocalDateTime import java.time.ZoneOffset @@ -34,5 +35,8 @@ interface HasPublishStatus { } // draft is non-op } + if(dao.publishStatus() != PublishStatus.Workspace && dao is CollectionDao) { + dao.workspaceOwner = StringUtils.EMPTY + } } } From 29cbef7e78a6a50c0f2f630cf06b48c8e68ca5f7 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 3 Feb 2023 11:44:25 -0600 Subject: [PATCH 029/150] setting status field as null-checked in ApiCollection --- .../kotlin/edu/wgu/osmt/api/model/ApiCollection.kt | 10 ++++++---- .../edu/wgu/osmt/collection/CollectionController.kt | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt index 06604f4b0..333bc0902 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollection.kt @@ -40,8 +40,8 @@ class ApiCollection(private val collection: Collection, private val ss: List Date: Thu, 2 Feb 2023 18:16:34 -0600 Subject: [PATCH 030/150] Using pipe collection --- ui/src/app/PublishStatus.ts | 6 +-- ui/src/app/app.module.ts | 2 + .../collection-skill-search.component.html | 6 +-- .../collection-skill-search.component.ts | 45 ++++++++++--------- ...blic-collection-detail-card.component.html | 4 +- ...public-collection-detail-card.component.ts | 5 +++ .../detail/manage-collection.component.html | 6 +-- .../detail/manage-collection.component.ts | 9 ++++ .../my-workspace/my-workspace.component.ts | 4 +- ui/src/app/pipes/collection.pipe.ts | 17 +++++++ .../richskill/list/skills-list.component.ts | 9 +++- 11 files changed, 79 insertions(+), 34 deletions(-) create mode 100644 ui/src/app/pipes/collection.pipe.ts diff --git a/ui/src/app/PublishStatus.ts b/ui/src/app/PublishStatus.ts index d15fad8c2..2702983e1 100644 --- a/ui/src/app/PublishStatus.ts +++ b/ui/src/app/PublishStatus.ts @@ -2,11 +2,11 @@ import {ApiCollectionSummary, ApiSkillSummary} from "./richskill/ApiSkillSummary export enum PublishStatus { Unarchived = "Unarchived", - Published = "Published", + Published = "published", Archived = "Archived", Deleted = "Deleted", - Draft = "Draft", - Workspace = "Workspace" + Draft = "draft", + Workspace = "workspace" } diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 95faca607..75d098040 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -98,6 +98,7 @@ import {NgIdleKeepaliveModule} from "@ng-idle/keepalive" import {LabelWithSelectComponent} from "./table/skills-library-table/label-with-select.component" import {LibraryExportComponent} from "./navigation/libraryexport.component" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" +import {CollectionPipe} from "./pipes/collection.pipe" export function initializeApp( appConfig: AppConfig, @@ -209,6 +210,7 @@ export function initializeApp( CheckerComponent, LabelWithSelectComponent, MyWorkspaceComponent, + CollectionPipe, ], imports: [ NgIdleKeepaliveModule.forRoot(), diff --git a/ui/src/app/collection/collection-skill-search.component.html b/ui/src/app/collection/collection-skill-search.component.html index ae7671163..3da166d55 100644 --- a/ui/src/app/collection/collection-skill-search.component.html +++ b/ui/src/app/collection/collection-skill-search.component.html @@ -7,9 +7,9 @@
    -

    Add RSDs to Collection

    +

    Add RSDs to {{collectionOrWorkspace(true)}}

    -

    Collection: {{collection.name}}

    +

    Collection: {{collection.name}}

    @@ -18,7 +18,7 @@

    Add RSDs to Collectio - +

    diff --git a/ui/src/app/collection/collection-skill-search.component.ts b/ui/src/app/collection/collection-skill-search.component.ts index 9b3f309b2..40096b829 100644 --- a/ui/src/app/collection/collection-skill-search.component.ts +++ b/ui/src/app/collection/collection-skill-search.component.ts @@ -1,19 +1,21 @@ -import {Component, OnInit} from "@angular/core"; -import {Observable} from "rxjs"; -import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../richskill/service/rich-skill-search.service"; -import {FormControl, FormGroup} from "@angular/forms"; -import {ActivatedRoute, Router} from "@angular/router"; -import {Title} from "@angular/platform-browser"; -import {Location} from "@angular/common"; -import {CollectionService} from "./service/collection.service"; -import {ToastService} from "../toast/toast.service"; -import {ApiCollection} from "./ApiCollection"; -import {RichSkillService} from "../richskill/service/rich-skill.service"; -import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions"; -import {ApiSkillSummary} from "../richskill/ApiSkillSummary"; -import {SkillsListComponent} from "../richskill/list/skills-list.component"; -import {ApiTaskResult} from "../task/ApiTaskResult"; -import {AuthService} from "../auth/auth-service"; +import {Component, OnInit} from "@angular/core" +import {Observable} from "rxjs" +import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../richskill/service/rich-skill-search.service" +import {FormControl, FormGroup} from "@angular/forms" +import {ActivatedRoute, Router} from "@angular/router" +import {Title} from "@angular/platform-browser" +import {Location} from "@angular/common" +import {CollectionService} from "./service/collection.service" +import {ToastService} from "../toast/toast.service" +import {ApiCollection} from "./ApiCollection" +import {RichSkillService} from "../richskill/service/rich-skill.service" +import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions" +import {ApiSkillSummary} from "../richskill/ApiSkillSummary" +import {SkillsListComponent} from "../richskill/list/skills-list.component" +import {ApiTaskResult} from "../task/ApiTaskResult" +import {AuthService} from "../auth/auth-service" +import {PublishStatus} from "../PublishStatus" +import {CollectionPipe} from "../pipes/collection.pipe" @Component({ selector: "app-collection-skill-search", @@ -50,7 +52,10 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen this.uuidParam = this.route.snapshot.paramMap.get("uuid") || undefined if (this.uuidParam != null) { this.collectionLoaded = this.collectionService.getCollectionByUUID(this.uuidParam) - this.collectionLoaded.subscribe(it => this.collection = it) + this.collectionLoaded.subscribe(it => { + this.collection = it + this.collection.status = PublishStatus.Workspace // TODO: remove + }) } } @@ -86,7 +91,7 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen rowActions(): TableActionDefinition[] { return [ new TableActionDefinition({ - label: "Add to Collection", + label: `Add to ${this.collectionOrWorkspace(true)}`, callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), }) ] @@ -105,7 +110,7 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickBackToTop(action, skill), }), new TableActionDefinition({ - label: "Add to Collection", + label: `Add to ${this.collectionOrWorkspace(true)}`, icon: "collection", primary: true, callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), @@ -123,7 +128,7 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen this.collectionUpdated.subscribe(result => { if (result) { this.toastService.hideBlockingLoader() - const message = `You added ${selectedCount} RSD${selectedCount ? "s" : ""} to the collection ${this.collection?.name}.` + const message = `You added ${selectedCount} RSD${selectedCount ? "s" : ""} to the ${this.collectionOrWorkspace(false)} ${this.collection?.name}.` this.toastService.showToast("Success!", message) } }) diff --git a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html index a8c422d46..14a0f5d19 100644 --- a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html +++ b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html @@ -1,6 +1,6 @@

    - +

    {{collectionName}}

    @@ -9,7 +9,7 @@

    {{c

    Author: {{collectionAuthor}}

    -
    +
    - +

    @@ -139,7 +139,7 @@

    Confirm that you want

    - Confirm that you want to {{collection.status === "Workspace" ? "reset" : "delete"}} {{this.collection?.name}} + Confirm that you want to {{resetOrDelete}} {{this.collection?.name}}

    @@ -150,7 +150,7 @@

    Cancel

    diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index cb8e7de59..f6c3e833d 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -20,6 +20,7 @@ import {formatDate} from "@angular/common" import * as FileSaver from "file-saver" import {ITaskResult} from "../../task/ApiTaskResult" import {delay, retryWhen, switchMap} from "rxjs/operators" +import {CollectionPipe} from "../../pipes/collection.pipe" @Component({ selector: "app-manage-collection", @@ -376,6 +377,14 @@ export class ManageCollectionComponent extends SkillsListComponent implements On return false } + get resetOrDelete(): string { + return this.collection?.status === PublishStatus.Workspace ? "reset" : "delete" + } + + collectionOrWorkspace(includesMy: boolean): string { + return new CollectionPipe().transform(this.collection?.status, includesMy) + } + protected handleClickBackToTop(action: TableActionDefinition, skill?: ApiSkillSummary): boolean { this.focusAndScrollIntoView(this.titleElement.nativeElement, "h2") return false diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 2d457d04c..cafabb2e4 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -45,7 +45,7 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O } actionDefinitions(): TableActionDefinition[] { - this.collection ? this.collection.status = PublishStatus.Workspace : false + this.collection ? this.collection.status = PublishStatus.Workspace : false // TODO: remove return [ new TableActionDefinition({ label: "Add RSDs to My Workspace", @@ -66,7 +66,7 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O visible: () => true }), new TableActionDefinition({ - label: "Reset Collection", + label: "Reset My Workspace", icon: this.deleteIcon, callback: () => this.deleteCollectionAction(), visible: () => (this.collection?.skills?.length ?? 0) > 0 diff --git a/ui/src/app/pipes/collection.pipe.ts b/ui/src/app/pipes/collection.pipe.ts new file mode 100644 index 000000000..cb93f5837 --- /dev/null +++ b/ui/src/app/pipes/collection.pipe.ts @@ -0,0 +1,17 @@ +import {Pipe, PipeTransform} from "@angular/core" +import {PublishStatus} from "../PublishStatus" + +@Pipe({ + name: "collection" +}) +export class CollectionPipe implements PipeTransform { + transform(value: PublishStatus | undefined, includesMy?: boolean): string { + console.log(value) + const isWorkspace = value === PublishStatus.Workspace + if (isWorkspace) { + return includesMy ? "My Workspace" : "Workspace" + } + return "Collection" + } + +} diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 2b7b97253..8ffb78163 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -15,6 +15,8 @@ import {TableActionBarComponent} from "../../table/skills-library-table/table-ac import {AuthService} from "../../auth/auth-service"; import {ButtonAction} from "../../auth/auth-roles"; import {CollectionService} from "../../collection/service/collection.service" +import {ApiCollection} from "../../collection/ApiCollection" +import {CollectionPipe} from "../../pipes/collection.pipe" @Component({ @@ -25,6 +27,7 @@ export class SkillsListComponent extends QuickLinksHelper { from = 0 size = 50 + collection?: ApiCollection @ViewChild("titleHeading") titleElement!: ElementRef @ViewChild(TableActionBarComponent) tableActionBar!: TableActionBarComponent @@ -265,7 +268,7 @@ export class SkillsListComponent extends QuickLinksHelper { })) } else { actions.push(new TableActionDefinition({ - label: "Remove from Collection", + label: `Remove from ${this.collectionOrWorkspace(true)}`, icon: "dismiss", primary: true, callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickRemoveCollection(action, skill), @@ -403,4 +406,8 @@ export class SkillsListComponent extends QuickLinksHelper { focusActionBar(): void { this.tableActionBar.focus() } + + collectionOrWorkspace(includesMy: boolean): string { + return new CollectionPipe().transform(this.collection?.status, includesMy) + } } From 75b4c9ea4d25d8f4303f17af05879b0e45cf6bca Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 3 Feb 2023 11:58:45 -0600 Subject: [PATCH 031/150] Remove set status workspace --- .../collection/collection-skill-search.component.ts | 10 ++++------ ui/src/app/my-workspace/my-workspace.component.ts | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ui/src/app/collection/collection-skill-search.component.ts b/ui/src/app/collection/collection-skill-search.component.ts index 40096b829..f41b69afd 100644 --- a/ui/src/app/collection/collection-skill-search.component.ts +++ b/ui/src/app/collection/collection-skill-search.component.ts @@ -15,7 +15,6 @@ import {SkillsListComponent} from "../richskill/list/skills-list.component" import {ApiTaskResult} from "../task/ApiTaskResult" import {AuthService} from "../auth/auth-service" import {PublishStatus} from "../PublishStatus" -import {CollectionPipe} from "../pipes/collection.pipe" @Component({ selector: "app-collection-skill-search", @@ -52,10 +51,7 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen this.uuidParam = this.route.snapshot.paramMap.get("uuid") || undefined if (this.uuidParam != null) { this.collectionLoaded = this.collectionService.getCollectionByUUID(this.uuidParam) - this.collectionLoaded.subscribe(it => { - this.collection = it - this.collection.status = PublishStatus.Workspace // TODO: remove - }) + this.collectionLoaded.subscribe(it => this.collection = it) } } @@ -128,7 +124,9 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen this.collectionUpdated.subscribe(result => { if (result) { this.toastService.hideBlockingLoader() - const message = `You added ${selectedCount} RSD${selectedCount ? "s" : ""} to the ${this.collectionOrWorkspace(false)} ${this.collection?.name}.` + const isWorkspace = this.collection?.status === PublishStatus.Workspace + const baseMessage = `You added ${selectedCount} RSD${selectedCount ? "s" : ""} to the` + const message = ` ${baseMessage} ${this.collectionOrWorkspace(false)} ${ isWorkspace ? "" : this.collection?.name}.` this.toastService.showToast("Success!", message) } }) diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index cafabb2e4..75d1b3629 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -45,7 +45,6 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O } actionDefinitions(): TableActionDefinition[] { - this.collection ? this.collection.status = PublishStatus.Workspace : false // TODO: remove return [ new TableActionDefinition({ label: "Add RSDs to My Workspace", From e3a8e87464133c7f06755260b129dd1cfeee193e Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 3 Feb 2023 12:15:14 -0600 Subject: [PATCH 032/150] Create collection from workspace - Create a collection from workspace instead of change status of workspace to drat. --- .../app/my-workspace/my-workspace.component.spec.ts | 2 +- ui/src/app/my-workspace/my-workspace.component.ts | 12 +++++++----- ui/test/resource/mock-stubs.ts | 11 +++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index 2ef44784b..019529017 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -76,7 +76,7 @@ describe("MyWorkspaceComponent", () => { it("convert to collection action", () => { const router = TestBed.inject(Router) - const spy = spyOn(collectionService, "updateCollection").and.callThrough() + const spy = spyOn(collectionService, "createCollection").and.callThrough() const spyNavigate = spyOn(router, "navigate").and.callThrough() component["convertToCollectionAction"]() expect(spy).toHaveBeenCalled() diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 75d1b3629..25f188155 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -31,7 +31,6 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O } ngOnInit(): void { - console.log("child on init") this.reloadCollection() } @@ -79,10 +78,13 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O } private convertToCollectionAction(): void { - // @ts-ignore - const updateObject = new ApiCollectionUpdate({status: PublishStatus.Draft.toLowerCase()}) - this.collectionService.updateCollection(this.uuidParam ?? "", updateObject).subscribe(() => { - this.router.navigate(["/collections/" + this.uuidParam + "/manage"]) + const updateObject = new ApiCollectionUpdate({ + name: this.collection?.name, + author: this.collection?.author, + skills: {add: this.collection?.skills.map(s => (s as any).uuid)} + }) + this.collectionService.createCollection(updateObject).subscribe(newCollection => { + this.router.navigate(["/collections/" + newCollection.uuid + "/manage"]) }) } diff --git a/ui/test/resource/mock-stubs.ts b/ui/test/resource/mock-stubs.ts index 0ca87081e..6d47c45ad 100644 --- a/ui/test/resource/mock-stubs.ts +++ b/ui/test/resource/mock-stubs.ts @@ -280,6 +280,17 @@ export class CollectionServiceStub { deleteCollection(uuid: string): Observable { return of(apiTaskResultForDeleteCollection) } + + createCollection(updateObject: ICollectionUpdate): Observable { + const date = new Date("2020-06-25T14:58:46.313Z") + return of(new ApiCollection(createMockCollection( + date, + date, + date, + date, + PublishStatus.Draft + ))) + } } // noinspection JSUnusedGlobalSymbols From e5300f94606993d6464bd94a8846f1f36bd9797c Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 3 Feb 2023 13:30:28 -0600 Subject: [PATCH 033/150] Index pipes --- ui/src/app/app.module.ts | 2 +- ui/src/app/collection/detail/manage-collection.component.ts | 2 +- ui/src/app/my-workspace/my-workspace.component.ts | 1 - ui/src/app/pipes/index.ts | 1 + ui/src/app/richskill/list/skills-list.component.ts | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 ui/src/app/pipes/index.ts diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 75d098040..4493868c5 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -98,7 +98,7 @@ import {NgIdleKeepaliveModule} from "@ng-idle/keepalive" import {LabelWithSelectComponent} from "./table/skills-library-table/label-with-select.component" import {LibraryExportComponent} from "./navigation/libraryexport.component" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" -import {CollectionPipe} from "./pipes/collection.pipe" +import {CollectionPipe} from "./pipes" export function initializeApp( appConfig: AppConfig, diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index f6c3e833d..e53d7fbb4 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -20,7 +20,7 @@ import {formatDate} from "@angular/common" import * as FileSaver from "file-saver" import {ITaskResult} from "../../task/ApiTaskResult" import {delay, retryWhen, switchMap} from "rxjs/operators" -import {CollectionPipe} from "../../pipes/collection.pipe" +import {CollectionPipe} from "../../pipes" @Component({ selector: "app-manage-collection", diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 25f188155..0f10a7662 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -7,7 +7,6 @@ import {ActivatedRoute, Router} from "@angular/router" import {Title} from "@angular/platform-browser" import {AuthService} from "../auth/auth-service" import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions" -import {PublishStatus} from "../PublishStatus" import {ApiSearch} from "../richskill/service/rich-skill-search.service" import {ApiCollectionUpdate} from "../collection/ApiCollection" diff --git a/ui/src/app/pipes/index.ts b/ui/src/app/pipes/index.ts new file mode 100644 index 000000000..795d12242 --- /dev/null +++ b/ui/src/app/pipes/index.ts @@ -0,0 +1 @@ +export * from "./collection.pipe" diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 8ffb78163..19e3e7782 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -16,7 +16,7 @@ import {AuthService} from "../../auth/auth-service"; import {ButtonAction} from "../../auth/auth-roles"; import {CollectionService} from "../../collection/service/collection.service" import {ApiCollection} from "../../collection/ApiCollection" -import {CollectionPipe} from "../../pipes/collection.pipe" +import {CollectionPipe} from "../../pipes" @Component({ From 99ae35b8c91fa82236b31aa25989fc97c07fd395 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 3 Feb 2023 13:34:26 -0600 Subject: [PATCH 034/150] Add pipe test --- ui/src/app/PublishStatus.ts | 4 ++-- ...c-collection-detail-card.component.spec.ts | 4 +++- ui/src/app/pipes/collection.pipe.spec.ts | 21 +++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 ui/src/app/pipes/collection.pipe.spec.ts diff --git a/ui/src/app/PublishStatus.ts b/ui/src/app/PublishStatus.ts index 2702983e1..d44ac97c8 100644 --- a/ui/src/app/PublishStatus.ts +++ b/ui/src/app/PublishStatus.ts @@ -2,10 +2,10 @@ import {ApiCollectionSummary, ApiSkillSummary} from "./richskill/ApiSkillSummary export enum PublishStatus { Unarchived = "Unarchived", - Published = "published", + Published = "Published", Archived = "Archived", Deleted = "Deleted", - Draft = "draft", + Draft = "Draft", Workspace = "workspace" } diff --git a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts index 94236cb82..1a3f1dcbf 100644 --- a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts +++ b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts @@ -6,6 +6,7 @@ import { RichSkillServiceStub } from "../../../../../test/resource/mock-stubs" import { RichSkillService } from "../../../richskill/service/rich-skill.service" import { ToastService } from "../../../toast/toast.service" import { PublicCollectionDetailCardComponent } from "./public-collection-detail-card.component" +import {CollectionPipe} from "../../../pipes" export function createComponent(T: Type): Promise { @@ -37,7 +38,8 @@ describe("PublicCollectionDetailCardComponent", () => { TestBed.configureTestingModule({ declarations: [ - PublicCollectionDetailCardComponent + PublicCollectionDetailCardComponent, + CollectionPipe ], imports: [ ], diff --git a/ui/src/app/pipes/collection.pipe.spec.ts b/ui/src/app/pipes/collection.pipe.spec.ts new file mode 100644 index 000000000..4a9cae18e --- /dev/null +++ b/ui/src/app/pipes/collection.pipe.spec.ts @@ -0,0 +1,21 @@ +import {CollectionPipe} from "./collection.pipe" +import {PublishStatus} from "../PublishStatus" + +describe("CollectionPipe", () => { + const pipe: CollectionPipe = new CollectionPipe() + + it("should return collection", () => { + const transform = pipe.transform(PublishStatus.Published) + expect(transform).toBe("Collection") + }) + + it("should return workspace", () => { + const transform = pipe.transform(PublishStatus.Workspace) + expect(transform).toBe("Workspace") + }) + + it("should return my workspace", () => { + const transform = pipe.transform(PublishStatus.Workspace, true) + expect(transform).toBe("My Workspace") + }) +}) From fe6ffccb769c0815d93493d6e36f3a89c1a6e85a Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 3 Feb 2023 17:44:48 -0600 Subject: [PATCH 035/150] adding ES filtering for the Richskill to not display the Workspace in its view, also removing Workspace from search results. --- .../kotlin/edu/wgu/osmt/api/model/ApiSkill.kt | 2 +- .../edu/wgu/osmt/collection/CollectionDao.kt | 2 +- .../osmt/elasticsearch/SearchController.kt | 21 ++++++++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt index cf775c1bf..497bb9dae 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt @@ -110,7 +110,7 @@ class ApiSkill(private val rsd: RichSkillDescriptor, private val cs: Set) : LongEntity(id), OutputsModel Date: Tue, 7 Feb 2023 10:19:53 -0600 Subject: [PATCH 036/150] refactoring workspace check on Collection --- api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt | 2 +- api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt index 497bb9dae..0bd7993bd 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSkill.kt @@ -110,7 +110,7 @@ class ApiSkill(private val rsd: RichSkillDescriptor, private val cs: Set Date: Tue, 7 Feb 2023 16:11:27 -0600 Subject: [PATCH 037/150] securing workspace endpoint to be accessible by admins and curators only --- api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt b/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt index 8510e3bba..4e7b10888 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt @@ -26,6 +26,7 @@ import edu.wgu.osmt.RoutePaths.TASK_DETAIL_SKILLS import edu.wgu.osmt.RoutePaths.TASK_DETAIL_TEXT import edu.wgu.osmt.api.model.ApiError import edu.wgu.osmt.config.AppConfig +import edu.wgu.osmt.db.WORKSPACE import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -130,6 +131,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() { .mvcMatchers(POST, COLLECTION_UPDATE).hasAnyAuthority(ADMIN, CURATOR) .mvcMatchers(POST, COLLECTION_SKILLS_UPDATE).hasAnyAuthority(ADMIN) .mvcMatchers(DELETE, COLLECTION_REMOVE).hasAnyAuthority(ADMIN) + .mvcMatchers(GET, WORKSPACE).hasAnyAuthority(ADMIN, CURATOR) .mvcMatchers("/api/**").hasAnyAuthority(ADMIN, CURATOR, VIEW, READ) } From d0040a8f77e5df098a2e200f847ed5d6255c4906 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 3 Feb 2023 16:19:25 -0600 Subject: [PATCH 038/150] Add collection pipe on templates --- ui/src/app/collection/detail/manage-collection.component.html | 2 +- ui/src/app/pipes/collection.pipe.ts | 1 - ui/src/app/richskill/list/skills-list.component.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/src/app/collection/detail/manage-collection.component.html b/ui/src/app/collection/detail/manage-collection.component.html index 89f64aedc..3aaa19fd0 100644 --- a/ui/src/app/collection/detail/manage-collection.component.html +++ b/ui/src/app/collection/detail/manage-collection.component.html @@ -34,7 +34,7 @@

    - {{totalCount}} RSDsRSD found in this collection based on + {{totalCount}} RSDsRSD found in this {{collectionOrWorkspace(false)}} based on {{matchingQuery[0]}} and diff --git a/ui/src/app/pipes/collection.pipe.ts b/ui/src/app/pipes/collection.pipe.ts index cb93f5837..325f7a5e2 100644 --- a/ui/src/app/pipes/collection.pipe.ts +++ b/ui/src/app/pipes/collection.pipe.ts @@ -6,7 +6,6 @@ import {PublishStatus} from "../PublishStatus" }) export class CollectionPipe implements PipeTransform { transform(value: PublishStatus | undefined, includesMy?: boolean): string { - console.log(value) const isWorkspace = value === PublishStatus.Workspace if (isWorkspace) { return includesMy ? "My Workspace" : "Workspace" diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 19e3e7782..05b76762b 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -200,7 +200,7 @@ export class SkillsListComponent extends QuickLinksHelper { })) } else { actions.push(new TableActionDefinition({ - label: "Remove from Collection", + label: `Remove from ${this.collectionOrWorkspace(true)}`, callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickRemoveCollection(action, skill), visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) })) From 7eaf879d40957e07ce27a33954a3158c6b16ec84 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 7 Feb 2023 12:05:57 -0600 Subject: [PATCH 039/150] Disable actions my workspace & confirm message - Convert to collection and reset workspace only are enabled if workspace has RSDs. - New functions to return messages depending on if is delete or reset. --- .../detail/manage-collection.component.html | 4 ++-- .../detail/manage-collection.component.spec.ts | 13 +++++++++++++ .../detail/manage-collection.component.ts | 8 ++++++-- .../my-workspace/my-workspace.component.spec.ts | 14 ++++++++++++++ .../app/my-workspace/my-workspace.component.ts | 16 ++++++++++++++-- 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/ui/src/app/collection/detail/manage-collection.component.html b/ui/src/app/collection/detail/manage-collection.component.html index 3aaa19fd0..4eb43213e 100644 --- a/ui/src/app/collection/detail/manage-collection.component.html +++ b/ui/src/app/collection/detail/manage-collection.component.html @@ -139,7 +139,7 @@

    Confirm that you want

    - Confirm that you want to {{resetOrDelete}} {{this.collection?.name}} + Confirm that you want to {{confirmMessageText}}

    @@ -150,7 +150,7 @@

    Cancel diff --git a/ui/src/app/collection/detail/manage-collection.component.spec.ts b/ui/src/app/collection/detail/manage-collection.component.spec.ts index e46d1cc7c..323cef7c8 100644 --- a/ui/src/app/collection/detail/manage-collection.component.spec.ts +++ b/ui/src/app/collection/detail/manage-collection.component.spec.ts @@ -552,4 +552,17 @@ describe("ManageCollectionComponent", () => { component.saveCsv(csvContent.body, "My Collection") expect(spySaveAS).toHaveBeenCalled() }) + + it("confirm message text", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) + component.collection.name = "Test Collection" + expect(component.confirmMessageText).toBe("delete Test Collection") + }) + + it("confirm button text", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) + expect(component.confirmButtonText).toBe("delete collection") + }) }) diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index e53d7fbb4..4c678739c 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -377,8 +377,12 @@ export class ManageCollectionComponent extends SkillsListComponent implements On return false } - get resetOrDelete(): string { - return this.collection?.status === PublishStatus.Workspace ? "reset" : "delete" + get confirmMessageText(): string { + return "delete " + (this.collection?.name ?? "") + } + + get confirmButtonText(): string { + return "delete collection" } collectionOrWorkspace(includesMy: boolean): string { diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index 019529017..c0be61ef3 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -13,6 +13,8 @@ import {EnvironmentService} from "../core/environment.service" import {CollectionService} from "../collection/service/collection.service" import {Router} from "@angular/router" import {ManageCollectionComponent} from "../collection/detail/manage-collection.component" +import {createMockCollection} from "../../../test/resource/mock-data" +import {PublishStatus} from "../PublishStatus" describe("MyWorkspaceComponent", () => { let component: MyWorkspaceComponent @@ -83,4 +85,16 @@ describe("MyWorkspaceComponent", () => { expect(spyNavigate).toHaveBeenCalled() }) + it("confirm message text", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) + expect(component.confirmMessageText).toBe("reset My Workspace") + }) + + it("confirm button text", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) + expect(component.confirmButtonText).toBe("reset My Workspace") + }) + }) diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 0f10a7662..12128ff96 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -60,17 +60,29 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O label: "Convert to Collection", icon: this.publishIcon, callback: () => this.convertToCollectionAction(), - visible: () => true + visible: () => !this.workspaceEmpty() }), new TableActionDefinition({ label: "Reset My Workspace", icon: this.deleteIcon, callback: () => this.deleteCollectionAction(), - visible: () => (this.collection?.skills?.length ?? 0) > 0 + visible: () => !this.workspaceEmpty() }) ] } + private workspaceEmpty(): boolean { + return (this.collection?.skills?.length ?? 0) === 0 + } + + get confirmMessageText(): string { + return "reset My Workspace" + } + + get confirmButtonText(): string { + return "reset My Workspace" + } + handleConfirmDeleteCollection(): void { this.submitSkillRemoval(new ApiSearch({uuids: this.collection?.skills.map(s => (s as any).uuid)})) this.template = "default" From 849d0af0935189807940f2653e5fa6774646c891 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 7 Feb 2023 16:51:52 -0600 Subject: [PATCH 040/150] Only admin and curator can see workspace --- ui/src/app/auth/auth-roles.ts | 4 +++- ui/src/app/navigation/header.component.html | 2 +- ui/src/app/navigation/header.component.ts | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/src/app/auth/auth-roles.ts b/ui/src/app/auth/auth-roles.ts index cca69e37d..c732772a0 100644 --- a/ui/src/app/auth/auth-roles.ts +++ b/ui/src/app/auth/auth-roles.ts @@ -14,6 +14,7 @@ export enum ButtonAction { LibraryExport, ExportDraftCollection, DeleteCollection, + MyWorkspace } export const ActionByRoles = new Map([ @@ -26,7 +27,8 @@ export const ActionByRoles = new Map([ [ButtonAction.CollectionSkillsUpdate, [OSMT_ADMIN]], [ButtonAction.LibraryExport, [OSMT_ADMIN]], [ButtonAction.ExportDraftCollection, [OSMT_ADMIN]], - [ButtonAction.DeleteCollection, [OSMT_ADMIN]] + [ButtonAction.DeleteCollection, [OSMT_ADMIN]], + [ButtonAction.MyWorkspace, [OSMT_ADMIN, OSMT_CURATOR]] ]) //TODO migrate AuthServiceWgu & AuthService.hasRole & isEnabledByRoles into a singleton here. HDN Sept 15, 2022 diff --git a/ui/src/app/navigation/header.component.html b/ui/src/app/navigation/header.component.html index 9ac81f756..49a042e49 100644 --- a/ui/src/app/navigation/header.component.html +++ b/ui/src/app/navigation/header.component.html @@ -26,7 +26,7 @@

    Site Navigation

  • Collections
  • -
  • +
  • My Workspace diff --git a/ui/src/app/navigation/header.component.ts b/ui/src/app/navigation/header.component.ts index e4ce2e653..c8ac6b033 100644 --- a/ui/src/app/navigation/header.component.ts +++ b/ui/src/app/navigation/header.component.ts @@ -4,6 +4,7 @@ import {Whitelabelled} from "../../whitelabel" import {AuthService} from "../auth/auth-service" import {ActivatedRoute, Router} from "@angular/router" import {AppConfig} from "../app.config" +import {ButtonAction} from "../auth/auth-roles" @Component({ selector: "app-header", @@ -11,6 +12,7 @@ import {AppConfig} from "../app.config" }) export class HeaderComponent extends Whitelabelled implements OnInit { menuExpanded: boolean = false + canHaveWorkspace = this.authService.isEnabledByRoles(ButtonAction.MyWorkspace) constructor(private authService: AuthService, private router: Router, private route: ActivatedRoute, private location: Location) { super() From e7ae7b4ffb777068aa40495ded7d532ad4a995b7 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 8 Feb 2023 11:19:28 -0600 Subject: [PATCH 041/150] setting case-insensitive when deserializing the enum status field from json --- .../edu/wgu/osmt/api/model/ApiCollectionUpdate.kt | 2 ++ .../wgu/osmt/collection/CollectionRepository.kt | 3 ++- .../main/kotlin/edu/wgu/osmt/db/UpdateObject.kt | 15 ++++++--------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollectionUpdate.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollectionUpdate.kt index 167a906ad..9f599de70 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollectionUpdate.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiCollectionUpdate.kt @@ -1,5 +1,6 @@ package edu.wgu.osmt.api.model +import com.fasterxml.jackson.annotation.JsonFormat import com.fasterxml.jackson.annotation.JsonProperty import edu.wgu.osmt.db.PublishStatus @@ -7,6 +8,7 @@ data class ApiCollectionUpdate( @JsonProperty("name") val name: String? = null, + @JsonFormat(with= [JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES]) @JsonProperty("status") val publishStatus: PublishStatus? = null, diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt index e909245cd..0de808e5e 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionRepository.kt @@ -282,7 +282,8 @@ class CollectionRepositoryImpl @Autowired constructor( val collectionUpdateObject = collectionUpdateObjectFromApi(collectionUpdate, richSkillRepository) val updateObjectWithId = collectionUpdateObject.copy( - id = existingCollectionId + id = existingCollectionId, + publishStatus = collectionUpdate.publishStatus ) return update(updateObjectWithId, user) diff --git a/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt b/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt index 717f7f0ac..af9f68e1d 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/db/UpdateObject.kt @@ -27,16 +27,13 @@ interface HasPublishStatus { dao.archiveDate = LocalDateTime.now(ZoneOffset.UTC) } } - else -> { - if (dao is CollectionDao) { - if(publishStatus != null) - dao.status = publishStatus as PublishStatus - } - - } // draft is non-op + else -> {} // draft is non-op } - if(dao.publishStatus() != PublishStatus.Workspace && dao is CollectionDao) { - dao.workspaceOwner = StringUtils.EMPTY + if(dao is CollectionDao && publishStatus != null) { + dao.status = publishStatus as PublishStatus + if (dao.status != PublishStatus.Workspace) { + dao.workspaceOwner = StringUtils.EMPTY + } } } } From 0fef6eb6258e6f4b186b89c35e236177d41f796b Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 9 Feb 2023 09:24:16 -0600 Subject: [PATCH 042/150] enabling skills update endpoint for curator role --- api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt b/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt index 4e7b10888..a403ac633 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/security/SecurityConfig.kt @@ -129,7 +129,7 @@ class SecurityConfig : WebSecurityConfigurerAdapter() { .mvcMatchers(POST, COLLECTION_CREATE).hasAnyAuthority(ADMIN, CURATOR) .mvcMatchers(POST, COLLECTION_PUBLISH).hasAnyAuthority(ADMIN) .mvcMatchers(POST, COLLECTION_UPDATE).hasAnyAuthority(ADMIN, CURATOR) - .mvcMatchers(POST, COLLECTION_SKILLS_UPDATE).hasAnyAuthority(ADMIN) + .mvcMatchers(POST, COLLECTION_SKILLS_UPDATE).hasAnyAuthority(ADMIN, CURATOR) .mvcMatchers(DELETE, COLLECTION_REMOVE).hasAnyAuthority(ADMIN) .mvcMatchers(GET, WORKSPACE).hasAnyAuthority(ADMIN, CURATOR) From 511580ebedcce5dc56387523b74f281d79e69271 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 9 Feb 2023 17:00:31 -0600 Subject: [PATCH 043/150] adding unit test for CollectionController workspace endpoint --- .../collection/CollectionControllerTest.kt | 73 ++ .../collection/CollectionRepositoryTest.kt | 12 + .../elasticsearch/SearchControllerTest.kt | 2 +- .../kotlin/edu/wgu/osmt/mockdata/MockData.kt | 2 +- api/src/test/resources/mock-data-v2.xml | 875 ++++++++++++++++++ api/src/test/resources/mock-data.xml | 14 +- 6 files changed, 969 insertions(+), 9 deletions(-) create mode 100644 api/src/test/kotlin/edu/wgu/osmt/collection/CollectionControllerTest.kt create mode 100644 api/src/test/resources/mock-data-v2.xml diff --git a/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionControllerTest.kt b/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionControllerTest.kt new file mode 100644 index 000000000..37157d95d --- /dev/null +++ b/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionControllerTest.kt @@ -0,0 +1,73 @@ +package edu.wgu.osmt.collection + +import edu.wgu.osmt.BaseDockerizedTest +import edu.wgu.osmt.HasDatabaseReset +import edu.wgu.osmt.HasElasticsearchReset +import edu.wgu.osmt.SpringTest +import edu.wgu.osmt.config.AppConfig +import edu.wgu.osmt.db.PublishStatus +import edu.wgu.osmt.jobcode.JobCodeEsRepo +import edu.wgu.osmt.keyword.KeywordEsRepo +import edu.wgu.osmt.mockdata.MockData +import edu.wgu.osmt.richskill.RichSkillEsRepo +import org.assertj.core.api.Assertions +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.security.oauth2.jwt.Jwt +import org.springframework.test.util.ReflectionTestUtils +import org.springframework.transaction.annotation.Transactional + +@Transactional +internal class CollectionControllerTest @Autowired constructor( + val collectionRepository: CollectionRepository, + val appConfig: AppConfig, + override val collectionEsRepo: CollectionEsRepo, + override val keywordEsRepo: KeywordEsRepo, + override val jobCodeEsRepo: JobCodeEsRepo, + override val richSkillEsRepo: RichSkillEsRepo +): SpringTest(), BaseDockerizedTest, HasDatabaseReset, HasElasticsearchReset { + + @Autowired + lateinit var collectionController: CollectionController + + private lateinit var mockData : MockData + + val userString = "unittestuser" + + val userEmail = "unit@test.user" + + + @BeforeAll + fun setup() { + mockData = MockData() + ReflectionTestUtils.setField(appConfig, "roleAdmin", "ROLE_Osmt_Admin") + } + + @Test + fun `workspaceByOwner() should retrieve an existing workspace`() { + // arrange + collectionRepository.create(CollectionUpdateObject(12345,"testCollection",null,null, PublishStatus.Workspace), userString, userEmail) + val jwt = Jwt.withTokenValue("foo").header("foo", "foo").claim("email", userEmail).build() + + // act + val result = collectionController.workspaceByOwner(jwt) + + // assert + Assertions.assertThat(result).isNotNull + } + + @Test + fun `workspaceByOwner() should create a workspace if it does not exist`() { + // arrange + val jwt = Jwt.withTokenValue("foo").header("foo", "foo").claim("email", userEmail).build() + + // act + Assertions.assertThat(collectionRepository.findAll().toList()).hasSize(0) + val result = collectionController.workspaceByOwner(jwt) + + // assert + Assertions.assertThat(collectionRepository.findAll().toList()).hasSize(1) + Assertions.assertThat(result).isNotNull + } +} \ No newline at end of file diff --git a/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt b/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt index ab47c75a2..194b68018 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/collection/CollectionRepositoryTest.kt @@ -150,6 +150,17 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes assertThat(collectionDao).isNotNull } + @Test + fun `findByOwner() should find an existing collection`() { + // Act + collectionRepository.create(CollectionUpdateObject(12345,"testCollection",null,null,PublishStatus.Workspace), userString, userEmail) + val collectionDao = collectionRepository.findByOwner("unit@test.user") + + // Assert + assertThat(collectionDao).isNotNull + assertThat(collectionDao!!.workspaceOwner).isEqualTo(userEmail) + } + @Test fun testChangeStatusesForTask() { // Arrange @@ -169,6 +180,7 @@ class CollectionRepositoryTest: SpringTest(), BaseDockerizedTest, HasDatabaseRes } + @Test fun testChangeStatusesForTaskWithCollectionId() { // Arrange val skillCount = 3 diff --git a/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/SearchControllerTest.kt b/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/SearchControllerTest.kt index 212bcd9d2..c1514256e 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/SearchControllerTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/elasticsearch/SearchControllerTest.kt @@ -51,7 +51,7 @@ internal class SearchControllerTest @Autowired constructor( UriComponentsBuilder.newInstance(), 50, 0, - arrayOf("draft", "published"), + arrayOf("draft", "published", "workspace"), "", ApiSearch(advanced = ApiAdvancedSearch(collectionName = collectionDoc?.name)), nullJwt) diff --git a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt index 1bb9bb40e..d23ae65e9 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt @@ -41,7 +41,7 @@ class MockData { appConfig = createAppConfig() try { - val filename = "mock-data.xml" + val filename = "mock-data-v2.xml" val file = this::class.java.classLoader.getResource(filename) if (file == null) { log.error("Unable to open {}", filename) diff --git a/api/src/test/resources/mock-data-v2.xml b/api/src/test/resources/mock-data-v2.xml new file mode 100644 index 000000000..26641159a --- /dev/null +++ b/api/src/test/resources/mock-data-v2.xml @@ -0,0 +1,875 @@ + + + 552021-06-14 14:35:07.816233Computer and Information Research Scientists15-1220bls + 582021-06-14 14:35:08.150119Software and Web Developers, Programmers, and Testers15-1250bls + 592021-06-14 14:35:08.264118Miscellaneous Computer Occupations15-1290bls + 4662021-06-14 14:35:42.920525Computer Occupations15-1200bls + 5602021-06-14 14:35:50.697073Computer and Mathematical Occupations15-0000bls + 6562021-06-14 14:36:07.538865Computer and Mathematical OccupationsComputer OccupationsComputer and Information Research ScientistsComputer and Information Research Scientists15-1221Computer and Information Research Scientistsbls + 6632021-06-14 14:36:08.981137Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersComputer Programmers15-1251Computer Programmersbls + 6642021-06-14 14:36:09.163140Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersSoftware Developers15-1252Software Developersbls + 6652021-06-14 14:36:09.374136Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersSoftware Quality Assurance Analysts and Testers15-1253Software Quality Assurance Analysts and Testersbls + 6662021-06-14 14:36:09.580135Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersWeb Developers15-1254Web Developersbls + 6672021-06-14 14:36:09.756142Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersWeb and Digital Interface Designers15-1255Web and Digital Interface Designersbls + 6682021-06-14 14:36:09.933680Computer and Mathematical OccupationsComputer OccupationsMiscellaneous Computer OccupationsComputer Occupations, All Other15-1299Computer Occupations, All Otherbls + 832021-06-14 14:35:10.335862Miscellaneous Engineers17-2190bls + 4692021-06-14 14:35:43.132983Engineers17-2000bls + 5612021-06-14 14:35:50.772069Architecture and Engineering Occupations17-0000bls + 6962021-06-14 14:36:15.237783Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199Engineers, All Otherbls + 16262021-06-14 14:41:00.763365Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.00Engineers, All OtherAll engineers not listed separately.o*net + 16272021-06-14 14:41:00.950419Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.03Energy Engineers, Except Wind and SolarDesign, develop, or evaluate energy-related projects or programs to reduce energy costs or improve energy efficiency during the designing, building, or remodeling stages of construction. May specialize in electrical systems; heating, ventilation, and air-conditioning (HVAC) systems; green buildings; lighting; air quality; or energy procurement.o*net + 16282021-06-14 14:41:01.168416Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.05Mechatronics EngineersResearch, design, develop, or test automation, intelligent systems, smart devices, or industrial systems control.o*net + 16292021-06-14 14:41:01.308422Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.06Microsystems EngineersResearch, design, develop, or test microelectromechanical systems (MEMS) devices.o*net + 16302021-06-14 14:41:01.470948Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.07Photonics EngineersDesign technologies specializing in light information or light energy, such as laser or fiber optics technology.o*net + 16312021-06-14 14:41:01.600983Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.08Robotics EngineersResearch, design, develop, or test robotic applications.o*net + 16322021-06-14 14:41:01.717984Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.09Nanosystems EngineersDesign, develop, or supervise the production of materials, devices, or systems of unique molecular or macromolecular composition, applying principles of nanoscale physics and electrical, chemical, or biological engineering.o*net + 16332021-06-14 14:41:01.828033Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.10Wind Energy EngineersDesign underground or overhead wind farm collector systems and prepare and develop site specifications.o*net + 16342021-06-14 14:41:01.951999Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.11Solar Energy Systems EngineersPerform site-specific engineering analysis or evaluation of energy efficiency and solar projects involving residential, commercial, or industrial customers. Design solar domestic hot water and space heating systems for new and existing structures, applying knowledge of structural energy requirements, local climates, solar technology, and thermodynamics.o*net + 24642021-06-14 14:43:16.18997717-2199.01 + 24652021-06-14 14:43:16.26429117-2199.02 + 24662021-06-14 14:43:16.32727817-2199.04 + 362021-06-14 14:35:05.937825Human Resources Workers13-1070bls + 4642021-06-14 14:35:42.779495Business Operations Specialists13-1000bls + 5592021-06-14 14:35:50.629074Business and Financial Operations Occupations13-0000bls + 6272021-06-14 14:36:01.870292Business and Financial Operations OccupationsBusiness Operations SpecialistsHuman Resources WorkersHuman Resources Specialists13-1071Human Resources Specialistsbls + 15212021-06-14 14:40:47.349382Business and Financial Operations OccupationsBusiness Operations SpecialistsHuman Resources WorkersHuman Resources Specialists13-1071.00Human Resources SpecialistsRecruit, screen, interview, or place individuals within an organization. May perform other activities in multiple human resources areas.o*net + 1432021-06-14 14:35:15.618938Librarians and Media Collections Specialists25-4020bls + 1462021-06-14 14:35:15.839679Instructional Coordinators25-9030bls + 1482021-06-14 14:35:16.012678Miscellaneous Educational Instruction and Library Workers25-9090bls + 4832021-06-14 14:35:44.269576Librarians, Curators, and Archivists25-4000bls + 4842021-06-14 14:35:44.345570Other Educational Instruction and Library Occupations25-9000bls + 5652021-06-14 14:35:51.039073Educational Instruction and Library Occupations25-0000bls + 8432021-06-14 14:36:44.195876Educational Instruction and Library OccupationsLibrarians, Curators, and ArchivistsLibrarians and Media Collections SpecialistsLibrarians and Media Collections Specialists25-4022Librarians and Media Collections Specialistsbls + 8462021-06-14 14:36:44.764330Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsInstructional CoordinatorsInstructional Coordinators25-9031Instructional Coordinatorsbls + 8512021-06-14 14:36:45.647883Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsMiscellaneous Educational Instruction and Library WorkersEducational Instruction and Library Workers, All Other25-9099Educational Instruction and Library Workers, All Otherbls + 18082021-06-14 14:41:22.978010Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsInstructional CoordinatorsInstructional Coordinators25-9031.00Instructional CoordinatorsDevelop instructional material, coordinate educational content, and incorporate current technology into instruction in order to provide guidelines to educators and instructors for developing curricula and conducting courses. May train and coach teachers. Includes educational consultants and specialists, and instructional material directors.o*net + 18132021-06-14 14:41:23.716104Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsMiscellaneous Educational Instruction and Library WorkersEducational Instruction and Library Workers, All Other25-9099.00Educational Instruction and Library Workers, All OtherAll educational instruction and library workers not listed separately.o*net + 24672021-06-14 14:43:18.13508125-9011 + 24682021-06-14 14:43:18.18505025-9011.00 + 24692021-06-14 14:43:18.23704825-9031.01 + 1232021-06-14 14:35:13.879463Math and Computer Science Teachers, Postsecondary25-1020bls + 1252021-06-14 14:35:14.050352Life Sciences Teachers, Postsecondary25-1040bls + 1262021-06-14 14:35:14.130683Physical Sciences Teachers, Postsecondary25-1050bls + 1292021-06-14 14:35:14.405516Education and Library Science Teachers, Postsecondary25-1080bls + 1342021-06-14 14:35:14.860508Elementary and Middle School Teachers25-2020bls + 1352021-06-14 14:35:14.935266Secondary School Teachers25-2030bls + 1362021-06-14 14:35:15.014270Special Education Teachers25-2050bls + 4802021-06-14 14:35:44.014573Postsecondary Teachers25-1000bls + 4812021-06-14 14:35:44.123566Preschool, Elementary, Middle, Secondary, and Special Education Teachers25-2000bls + 7862021-06-14 14:36:33.019169Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryComputer Science Teachers, Postsecondary25-1021Computer Science Teachers, Postsecondarybls + 7872021-06-14 14:36:33.223730Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryMathematical Science Teachers, Postsecondary25-1022Mathematical Science Teachers, Postsecondarybls + 7902021-06-14 14:36:33.763445Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryAgricultural Sciences Teachers, Postsecondary25-1041Agricultural Sciences Teachers, Postsecondarybls + 7912021-06-14 14:36:33.934452Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryBiological Science Teachers, Postsecondary25-1042Biological Science Teachers, Postsecondarybls + 7922021-06-14 14:36:34.167554Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryForestry and Conservation Science Teachers, Postsecondary25-1043Forestry and Conservation Science Teachers, Postsecondarybls + 7932021-06-14 14:36:34.329559Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryAtmospheric, Earth, Marine, and Space Sciences Teachers, Postsecondary25-1051Atmospheric, Earth, Marine, and Space Sciences Teachers, Postsecondarybls + 7942021-06-14 14:36:34.555592Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryChemistry Teachers, Postsecondary25-1052Chemistry Teachers, Postsecondarybls + 7952021-06-14 14:36:34.768202Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryEnvironmental Science Teachers, Postsecondary25-1053Environmental Science Teachers, Postsecondarybls + 7962021-06-14 14:36:34.947255Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryPhysics Teachers, Postsecondary25-1054Physics Teachers, Postsecondarybls + 8072021-06-14 14:36:37.178871Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryEducation Teachers, Postsecondary25-1081Education Teachers, Postsecondarybls + 8082021-06-14 14:36:37.349869Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryLibrary Science Teachers, Postsecondary25-1082Library Science Teachers, Postsecondarybls + 8242021-06-14 14:36:40.350773Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersElementary School Teachers, Except Special Education25-2021Elementary School Teachers, Except Special Educationbls + 8252021-06-14 14:36:40.577300Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersMiddle School Teachers, Except Special and Career/Technical Education25-2022Middle School Teachers, Except Special and Career/Technical Educationbls + 8262021-06-14 14:36:40.736304Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersCareer/Technical Education Teachers, Middle School25-2023Career/Technical Education Teachers, Middle Schoolbls + 8272021-06-14 14:36:40.911865Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersSecondary School Teachers, Except Special and Career/Technical Education25-2031Secondary School Teachers, Except Special and Career/Technical Educationbls + 8282021-06-14 14:36:41.120863Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersCareer/Technical Education Teachers, Secondary School25-2032Career/Technical Education Teachers, Secondary Schoolbls + 8292021-06-14 14:36:41.291860Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Preschool25-2051Special Education Teachers, Preschoolbls + 8302021-06-14 14:36:41.511830Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Kindergarten25-2055Special Education Teachers, Kindergartenbls + 8312021-06-14 14:36:41.844828Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Elementary School25-2056Special Education Teachers, Elementary Schoolbls + 8322021-06-14 14:36:42.084830Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Middle School25-2057Special Education Teachers, Middle Schoolbls + 8332021-06-14 14:36:42.276837Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Secondary School25-2058Special Education Teachers, Secondary Schoolbls + 8342021-06-14 14:36:42.527828Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, All Other25-2059Special Education Teachers, All Otherbls + 17472021-06-14 14:41:15.676973Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryComputer Science Teachers, Postsecondary25-1021.00Computer Science Teachers, PostsecondaryTeach courses in computer science. May specialize in a field of computer science, such as the design and function of computers or operations and research analysis. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17482021-06-14 14:41:15.779980Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryMathematical Science Teachers, Postsecondary25-1022.00Mathematical Science Teachers, PostsecondaryTeach courses pertaining to mathematical concepts, statistics, and actuarial science and to the application of original and standardized mathematical techniques in solving specific problems and situations. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17512021-06-14 14:41:16.133977Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryAgricultural Sciences Teachers, Postsecondary25-1041.00Agricultural Sciences Teachers, PostsecondaryTeach courses in the agricultural sciences. Includes teachers of agronomy, dairy sciences, fisheries management, horticultural sciences, poultry sciences, range management, and agricultural soil conservation. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17522021-06-14 14:41:16.240977Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryBiological Science Teachers, Postsecondary25-1042.00Biological Science Teachers, PostsecondaryTeach courses in biological sciences. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17532021-06-14 14:41:16.341978Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryForestry and Conservation Science Teachers, Postsecondary25-1043.00Forestry and Conservation Science Teachers, PostsecondaryTeach courses in forestry and conservation science. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17542021-06-14 14:41:16.473976Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryAtmospheric, Earth, Marine, and Space Sciences Teachers, Postsecondary25-1051.00Atmospheric, Earth, Marine, and Space Sciences Teachers, PostsecondaryTeach courses in the physical sciences, except chemistry and physics. Includes both teachers primarily engaged in teaching, and those who do a combination of teaching and research.o*net + 17552021-06-14 14:41:16.583011Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryChemistry Teachers, Postsecondary25-1052.00Chemistry Teachers, PostsecondaryTeach courses pertaining to the chemical and physical properties and compositional changes of substances. Work may include providing instruction in the methods of qualitative and quantitative chemical analysis. Includes both teachers primarily engaged in teaching, and those who do a combination of teaching and research.o*net + 17562021-06-14 14:41:16.693662Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryEnvironmental Science Teachers, Postsecondary25-1053.00Environmental Science Teachers, PostsecondaryTeach courses in environmental science. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17572021-06-14 14:41:16.806212Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryPhysics Teachers, Postsecondary25-1054.00Physics Teachers, PostsecondaryTeach courses pertaining to the laws of matter and energy. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17682021-06-14 14:41:18.284611Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryEducation Teachers, Postsecondary25-1081.00Education Teachers, PostsecondaryTeach courses pertaining to education, such as counseling, curriculum, guidance, instruction, teacher education, and teaching English as a second language. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17692021-06-14 14:41:18.395631Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryLibrary Science Teachers, Postsecondary25-1082.00Library Science Teachers, PostsecondaryTeach courses in library science. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17852021-06-14 14:41:20.206382Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersElementary School Teachers, Except Special Education25-2021.00Elementary School Teachers, Except Special EducationTeach academic and social skills to students at the elementary school level.o*net + 17862021-06-14 14:41:20.330615Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersMiddle School Teachers, Except Special and Career/Technical Education25-2022.00Middle School Teachers, Except Special and Career/Technical EducationTeach one or more subjects to students at the middle, intermediate, or junior high school level.o*net + 17872021-06-14 14:41:20.439639Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersCareer/Technical Education Teachers, Middle School25-2023.00Career/Technical Education Teachers, Middle SchoolTeach occupational, vocational, career, or technical subjects to students at the middle, intermediate, or junior high school level.o*net + 17882021-06-14 14:41:20.547611Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersSecondary School Teachers, Except Special and Career/Technical Education25-2031.00Secondary School Teachers, Except Special and Career/Technical EducationTeach one or more subjects to students at the secondary school level.o*net + 17892021-06-14 14:41:20.652610Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersCareer/Technical Education Teachers, Secondary School25-2032.00Career/Technical Education Teachers, Secondary SchoolTeach occupational, vocational, career, or technical subjects to students at the secondary school level.o*net + 17902021-06-14 14:41:20.761654Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Preschool25-2051.00Special Education Teachers, PreschoolTeach academic, social, and life skills to preschool-aged students with learning, emotional, or physical disabilities. Includes teachers who specialize and work with students who are blind or have visual impairments; students who are deaf or have hearing impairments; and students with intellectual disabilities.o*net + 17952021-06-14 14:41:21.351396Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, All Other25-2059.00Special Education Teachers, All OtherAll special education teachers not listed separately.o*net + 17962021-06-14 14:41:21.483396Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, All Other25-2059.01Adapted Physical Education SpecialistsProvide individualized physical education instruction or services to children, youth, or adults with exceptional physical needs due to gross motor developmental delays or other impairments.o*net + 24702021-06-14 14:43:18.61349525-2052.00 + 24712021-06-14 14:43:18.66351625-2053.00 + 24722021-06-14 14:43:18.70749325-2054.00 + 1332021-06-14 14:35:14.786512Preschool and Kindergarten Teachers25-2010bls + 8222021-06-14 14:36:40.003644Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersPreschool Teachers, Except Special Education25-2011Preschool Teachers, Except Special Educationbls + 8232021-06-14 14:36:40.181432Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersKindergarten Teachers, Except Special Education25-2012Kindergarten Teachers, Except Special Educationbls + 17832021-06-14 14:41:19.969383Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersPreschool Teachers, Except Special Education25-2011.00Preschool Teachers, Except Special EducationInstruct preschool-aged students, following curricula or lesson plans, in activities designed to promote social, physical, and intellectual growth.o*net + 17842021-06-14 14:41:20.091378Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersKindergarten Teachers, Except Special Education25-2012.00Kindergarten Teachers, Except Special EducationTeach academic and social skills to kindergarten students.o*net + 1372021-06-14 14:35:15.091266Adult Basic Education, Adult Secondary Education, and English as a Second Language Instructors25-3010bls + 4822021-06-14 14:35:44.197570Other Teachers and Instructors25-3000bls + 5842021-06-14 14:35:53.352438Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersAdvertising and Promotions ManagersAdvertising and Promotions Managers11-2011Advertising and Promotions Managersbls + 5852021-06-14 14:35:53.603438Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersMarketing Managers11-2021Marketing Managersbls + 5862021-06-14 14:35:53.805439Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersSales Managers11-2022Sales Managersbls + 6372021-06-14 14:36:04.054137Business and Financial Operations OccupationsBusiness Operations SpecialistsMarket Research Analysts and Marketing SpecialistsMarket Research Analysts and Marketing Specialists13-1161Market Research Analysts and Marketing Specialistsbls + 6552021-06-14 14:36:07.280337Computer and Mathematical OccupationsComputer OccupationsComputer and Information AnalystsInformation Security Analysts15-1212Information Security Analystsbls + 17972021-06-14 14:41:21.590398Educational Instruction and Library OccupationsOther Teachers and InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language Instructors25-3011.00Adult Basic Education, Adult Secondary Education, and English as a Second Language InstructorsTeach or instruct out-of-school youths and adults in basic education, literacy, or English as a Second Language classes, or in classes for earning a high school equivalency credential.o*net + 8352021-06-14 14:36:42.698831Educational Instruction and Library OccupationsOther Teachers and InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language Instructors25-3011Adult Basic Education, Adult Secondary Education, and English as a Second Language Instructorsbls + 1222021-06-14 14:35:13.775455Business Teachers, Postsecondary25-1010bls + 1272021-06-14 14:35:14.220690Social Sciences Teachers, Postsecondary25-1060bls + 1282021-06-14 14:35:14.303507Health Teachers, Postsecondary25-1070bls + 1312021-06-14 14:35:14.610505Arts, Communications, History, and Humanities Teachers, Postsecondary25-1120bls + 7852021-06-14 14:36:32.836207Educational Instruction and Library OccupationsPostsecondary TeachersBusiness Teachers, PostsecondaryBusiness Teachers, Postsecondary25-1011Business Teachers, Postsecondarybls + 7972021-06-14 14:36:35.111285Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryAnthropology and Archeology Teachers, Postsecondary25-1061Anthropology and Archeology Teachers, Postsecondarybls + 7982021-06-14 14:36:35.288844Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryArea, Ethnic, and Cultural Studies Teachers, Postsecondary25-1062Area, Ethnic, and Cultural Studies Teachers, Postsecondarybls + 7992021-06-14 14:36:35.490822Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryEconomics Teachers, Postsecondary25-1063Economics Teachers, Postsecondarybls + 8002021-06-14 14:36:35.674830Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryGeography Teachers, Postsecondary25-1064Geography Teachers, Postsecondarybls + 8012021-06-14 14:36:35.853826Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPolitical Science Teachers, Postsecondary25-1065Political Science Teachers, Postsecondarybls + 8022021-06-14 14:36:36.033821Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPsychology Teachers, Postsecondary25-1066Psychology Teachers, Postsecondarybls + 8032021-06-14 14:36:36.307824Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySociology Teachers, Postsecondary25-1067Sociology Teachers, Postsecondarybls + 8042021-06-14 14:36:36.614824Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySocial Sciences Teachers, Postsecondary, All Other25-1069Social Sciences Teachers, Postsecondary, All Otherbls + 8052021-06-14 14:36:36.809822Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryHealth Specialties Teachers, Postsecondary25-1071Health Specialties Teachers, Postsecondarybls + 8062021-06-14 14:36:36.983350Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryNursing Instructors and Teachers, Postsecondary25-1072Nursing Instructors and Teachers, Postsecondarybls + 8122021-06-14 14:36:38.101868Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryArt, Drama, and Music Teachers, Postsecondary25-1121Art, Drama, and Music Teachers, Postsecondarybls + 8132021-06-14 14:36:38.301866Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryCommunications Teachers, Postsecondary25-1122Communications Teachers, Postsecondarybls + 8142021-06-14 14:36:38.497867Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryEnglish Language and Literature Teachers, Postsecondary25-1123English Language and Literature Teachers, Postsecondarybls + 8152021-06-14 14:36:38.693918Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryForeign Language and Literature Teachers, Postsecondary25-1124Foreign Language and Literature Teachers, Postsecondarybls + 8162021-06-14 14:36:38.875920Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryHistory Teachers, Postsecondary25-1125History Teachers, Postsecondarybls + 8172021-06-14 14:36:39.035525Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryPhilosophy and Religion Teachers, Postsecondary25-1126Philosophy and Religion Teachers, Postsecondarybls + 17462021-06-14 14:41:15.569972Educational Instruction and Library OccupationsPostsecondary TeachersBusiness Teachers, PostsecondaryBusiness Teachers, Postsecondary25-1011.00Business Teachers, PostsecondaryTeach courses in business administration and management, such as accounting, finance, human resources, labor and industrial relations, marketing, and operations research. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17582021-06-14 14:41:16.923279Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryAnthropology and Archeology Teachers, Postsecondary25-1061.00Anthropology and Archeology Teachers, PostsecondaryTeach courses in anthropology or archeology. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17592021-06-14 14:41:17.071270Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryArea, Ethnic, and Cultural Studies Teachers, Postsecondary25-1062.00Area, Ethnic, and Cultural Studies Teachers, PostsecondaryTeach courses pertaining to the culture and development of an area, an ethnic group, or any other group, such as Latin American studies, women's studies, or urban affairs. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17602021-06-14 14:41:17.206271Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryEconomics Teachers, Postsecondary25-1063.00Economics Teachers, PostsecondaryTeach courses in economics. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17612021-06-14 14:41:17.331270Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryGeography Teachers, Postsecondary25-1064.00Geography Teachers, PostsecondaryTeach courses in geography. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17622021-06-14 14:41:17.475611Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPolitical Science Teachers, Postsecondary25-1065.00Political Science Teachers, PostsecondaryTeach courses in political science, international affairs, and international relations. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17632021-06-14 14:41:17.614613Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPsychology Teachers, Postsecondary25-1066.00Psychology Teachers, PostsecondaryTeach courses in psychology, such as child, clinical, and developmental psychology, and psychological counseling. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17642021-06-14 14:41:17.742611Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySociology Teachers, Postsecondary25-1067.00Sociology Teachers, PostsecondaryTeach courses in sociology. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17652021-06-14 14:41:17.881616Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySocial Sciences Teachers, Postsecondary, All Other25-1069.00Social Sciences Teachers, Postsecondary, All OtherAll postsecondary social sciences teachers not listed separately.o*net + 17662021-06-14 14:41:18.020614Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryHealth Specialties Teachers, Postsecondary25-1071.00Health Specialties Teachers, PostsecondaryTeach courses in health specialties, in fields such as dentistry, laboratory technology, medicine, pharmacy, public health, therapy, and veterinary medicine.o*net + 17672021-06-14 14:41:18.151610Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryNursing Instructors and Teachers, Postsecondary25-1072.00Nursing Instructors and Teachers, PostsecondaryDemonstrate and teach patient care in classroom and clinical units to nursing students. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17732021-06-14 14:41:18.859666Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryArt, Drama, and Music Teachers, Postsecondary25-1121.00Art, Drama, and Music Teachers, PostsecondaryTeach courses in drama, music, and the arts including fine and applied art, such as painting and sculpture, or design and crafts. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17742021-06-14 14:41:18.969660Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryCommunications Teachers, Postsecondary25-1122.00Communications Teachers, PostsecondaryTeach courses in communications, such as organizational communications, public relations, radio/television broadcasting, and journalism. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17752021-06-14 14:41:19.076180Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryEnglish Language and Literature Teachers, Postsecondary25-1123.00English Language and Literature Teachers, PostsecondaryTeach courses in English language and literature, including linguistics and comparative literature. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17762021-06-14 14:41:19.193178Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryForeign Language and Literature Teachers, Postsecondary25-1124.00Foreign Language and Literature Teachers, PostsecondaryTeach languages and literature courses in languages other than English. Includes teachers of American Sign Language (ASL). Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17772021-06-14 14:41:19.322181Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryHistory Teachers, Postsecondary25-1125.00History Teachers, PostsecondaryTeach courses in human history and historiography. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 17782021-06-14 14:41:19.428201Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryPhilosophy and Religion Teachers, Postsecondary25-1126.00Philosophy and Religion Teachers, PostsecondaryTeach courses in philosophy, religion, and theology. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net + 1742021-06-14 14:35:18.271793Registered Nurses29-1140bls + 4892021-06-14 14:35:44.770602Healthcare Diagnosing or Treating Practitioners29-1000bls + 5672021-06-14 14:35:51.191070Healthcare Practitioners and Technical Occupations29-0000bls + 9132021-06-14 14:36:57.334513Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141Registered Nursesbls + 18832021-06-14 14:41:31.742171Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.00Registered NursesAssess patient health problems and needs, develop and implement nursing care plans, and maintain medical records. Administer nursing care to ill, injured, convalescent, or disabled patients. May advise patients on health maintenance and disease prevention or provide case management. Licensing or registration required.o*net + 18842021-06-14 14:41:31.853172Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.01Acute Care NursesProvide advanced nursing care for patients with acute conditions such as heart attacks, respiratory distress syndrome, or shock. May care for pre- and post-operative patients or perform advanced, invasive diagnostic or therapeutic procedures.o*net + 18852021-06-14 14:41:31.956175Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.02Advanced Practice Psychiatric NursesAssess, diagnose, and treat individuals and families with mental health or substance use disorders or the potential for such disorders. Apply therapeutic activities, including the prescription of medication, per state regulations, and the administration of psychotherapy.o*net + 18862021-06-14 14:41:32.054172Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.03Critical Care NursesProvide specialized nursing care for patients in critical or coronary care units.o*net + 18872021-06-14 14:41:32.149173Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.04Clinical Nurse SpecialistsDirect nursing staff in the provision of patient care in a clinical practice setting, such as a hospital, hospice, clinic, or home. Ensure adherence to established clinical policies, protocols, regulations, and standards.o*net + 542021-06-14 14:35:07.720267Computer and Information Analysts15-1210bls + 382021-06-14 14:35:06.135823Management Analysts13-1110bls + 432021-06-14 14:35:06.683829Market Research Analysts and Marketing Specialists13-1160bls + 6322021-06-14 14:36:02.838134Business and Financial Operations OccupationsBusiness Operations SpecialistsManagement AnalystsManagement Analysts13-1111Management Analystsbls + 6542021-06-14 14:36:07.109340Computer and Mathematical OccupationsComputer OccupationsComputer and Information AnalystsComputer Systems Analysts15-1211Computer Systems Analystsbls + 852021-06-14 14:35:10.541855Engineering Technologists and Technicians, Except Drafters17-3020bls + 4702021-06-14 14:35:43.196989Drafters, Engineering Technicians, and Mapping Technicians17-3000bls + 7012021-06-14 14:36:16.157401Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersAerospace Engineering and Operations Technologists and Technicians17-3021Aerospace Engineering and Operations Technologists and Techniciansbls + 7022021-06-14 14:36:16.322441Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersCivil Engineering Technologists and Technicians17-3022Civil Engineering Technologists and Techniciansbls + 7032021-06-14 14:36:16.537416Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectrical and Electronic Engineering Technologists and Technicians17-3023Electrical and Electronic Engineering Technologists and Techniciansbls + 7042021-06-14 14:36:16.713401Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectro-Mechanical and Mechatronics Technologists and Technicians17-3024Electro-Mechanical and Mechatronics Technologists and Techniciansbls + 7052021-06-14 14:36:16.891424Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEnvironmental Engineering Technologists and Technicians17-3025Environmental Engineering Technologists and Techniciansbls + 7062021-06-14 14:36:17.075524Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersIndustrial Engineering Technologists and Technicians17-3026Industrial Engineering Technologists and Techniciansbls + 7072021-06-14 14:36:17.242523Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersMechanical Engineering Technologists and Technicians17-3027Mechanical Engineering Technologists and Techniciansbls + 7082021-06-14 14:36:17.446525Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersCalibration Technologists and Technicians17-3028Calibration Technologists and Techniciansbls + 7092021-06-14 14:36:17.681532Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029Engineering Technologists and Technicians, Except Drafters, All Otherbls + 16392021-06-14 14:41:02.611002Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersAerospace Engineering and Operations Technologists and Technicians17-3021.00Aerospace Engineering and Operations Technologists and TechniciansOperate, install, adjust, and maintain integrated computer/communications systems, consoles, simulators, and other data acquisition, test, and measurement instruments and equipment, which are used to launch, track, position, and evaluate air and space vehicles. May record and interpret test data.o*net + 16402021-06-14 14:41:02.763683Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersCivil Engineering Technologists and Technicians17-3022.00Civil Engineering Technologists and TechniciansApply theory and principles of civil engineering in planning, designing, and overseeing construction and maintenance of structures and facilities under the direction of engineering staff or physical scientists.o*net + 16412021-06-14 14:41:02.910372Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectrical and Electronic Engineering Technologists and Technicians17-3023.00Electrical and Electronic Engineering Technologists and TechniciansApply electrical and electronic theory and related knowledge, usually under the direction of engineering staff, to design, build, repair, adjust, and modify electrical components, circuitry, controls, and machinery for subsequent evaluation and use by engineering staff in making engineering design decisions.o*net + 16422021-06-14 14:41:03.023374Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectro-Mechanical and Mechatronics Technologists and Technicians17-3024.00Electro-Mechanical and Mechatronics Technologists and TechniciansOperate, test, maintain, or adjust unmanned, automated, servomechanical, or electromechanical equipment. May operate unmanned submarines, aircraft, or other equipment to observe or record visual information at sites such as oil rigs, crop fields, buildings, or for similar infrastructure, deep ocean exploration, or hazardous waste removal. May assist engineers in testing and designing robotics equipment.o*net + 16432021-06-14 14:41:03.140367Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectro-Mechanical and Mechatronics Technologists and Technicians17-3024.01Robotics TechniciansBuild, install, test, or maintain robotic equipment or related automated production systems.o*net + 16442021-06-14 14:41:03.256374Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEnvironmental Engineering Technologists and Technicians17-3025.00Environmental Engineering Technologists and TechniciansApply theory and principles of environmental engineering to modify, test, and operate equipment and devices used in the prevention, control, and remediation of environmental problems, including waste treatment and site remediation, under the direction of engineering staff or scientists. May assist in the development of environmental remediation devices.o*net + 16452021-06-14 14:41:03.389368Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersIndustrial Engineering Technologists and Technicians17-3026.00Industrial Engineering Technologists and TechniciansApply engineering theory and principles to problems of industrial layout or manufacturing production, usually under the direction of engineering staff. May perform time and motion studies on worker operations in a variety of industries for purposes such as establishing standard production rates or improving efficiency.o*net + 16472021-06-14 14:41:03.643556Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersMechanical Engineering Technologists and Technicians17-3027.00Mechanical Engineering Technologists and TechniciansApply theory and principles of mechanical engineering to modify, develop, test, or adjust machinery and equipment under direction of engineering staff or physical scientists.o*net + 16482021-06-14 14:41:03.802557Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersMechanical Engineering Technologists and Technicians17-3027.01Automotive Engineering TechniciansAssist engineers in determining the practicality of proposed product design changes and plan and carry out tests on experimental test devices or equipment for performance, durability, or efficiency.o*net + 16502021-06-14 14:41:04.033585Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029.00Engineering Technologists and Technicians, Except Drafters, All OtherAll engineering technologists and technicians, except drafters, not listed separately.o*net + 16512021-06-14 14:41:04.147123Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029.01Non-Destructive Testing SpecialistsTest the safety of structures, vehicles, or vessels using x-ray, ultrasound, fiber optic or related equipment.o*net + 16522021-06-14 14:41:04.265321Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029.08Photonics TechniciansBuild, install, test, or maintain optical or fiber optic equipment, such as lasers, lenses, or mirrors, using spectrometers, interferometers, or related equipment.o*net + 24732021-06-14 14:43:40.61316417-3023.01 + 24742021-06-14 14:43:40.69216417-3023.03 + 24752021-06-14 14:43:40.76716717-3029.02 + 24762021-06-14 14:43:40.82716317-3029.03 + 24772021-06-14 14:43:40.87915917-3029.04 + 24782021-06-14 14:43:40.94516117-3029.05 + 24792021-06-14 14:43:41.00915817-3029.06 + 24802021-06-14 14:43:41.07316017-3029.07 + 24812021-06-14 14:43:41.12816117-3029.09 + 24822021-06-14 14:43:41.17616417-3029.10 + 24832021-06-14 14:43:41.22516317-3029.11 + 24842021-06-14 14:43:41.28315917-3029.12 + 24852021-06-14 14:43:41.63876015-1223 + 24862021-06-14 14:43:42.06675815-1222 + 572021-06-14 14:35:08.022117Database and Network Administrators and Architects15-1240bls + 6592021-06-14 14:36:08.060134Computer and Mathematical OccupationsComputer OccupationsDatabase and Network Administrators and ArchitectsComputer Network Architects15-1241Computer Network Architectsbls + 24872021-06-14 14:43:43.93671015-1121.00 + 24882021-06-14 14:43:44.05670815-1122.00 + 24892021-06-14 14:43:44.15570715-1143.00 + 24902021-06-14 14:43:44.27270915-1143.01 + 24912021-06-14 14:43:44.37871015-1132.00 + 24922021-06-14 14:43:44.45923415-1133.00 + 24932021-06-14 14:43:44.55223615-1199.09 + 24942021-06-14 14:43:46.38638815-1199.02 + 6612021-06-14 14:36:08.416136Computer and Mathematical OccupationsComputer OccupationsDatabase and Network Administrators and ArchitectsDatabase Architects15-1243Database Architectsbls + 1142021-06-14 14:35:12.923534Miscellaneous Community and Social Service Specialists21-1090bls + 4762021-06-14 14:35:43.735571Counselors, Social Workers, and Other Community and Social Service Specialists21-1000bls + 5632021-06-14 14:35:50.909071Community and Social Service Occupations21-0000bls + 7712021-06-14 14:36:30.012910Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsSocial and Human Service Assistants21-1093Social and Human Service Assistantsbls + 7722021-06-14 14:36:30.178940Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity Health Workers21-1094Community Health Workersbls + 7732021-06-14 14:36:30.349907Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity and Social Service Specialists, All Other21-1099Community and Social Service Specialists, All Otherbls + 17322021-06-14 14:41:14.044331Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsSocial and Human Service Assistants21-1093.00Social and Human Service AssistantsAssist other social and human service providers in providing client services in a wide variety of fields, such as psychology, rehabilitation, or social work, including support for families. May assist clients in identifying and obtaining available benefits and social and community services. May assist social workers with developing, organizing, and conducting programs to prevent and resolve problems relevant to substance abuse, human relationships, rehabilitation, or dependent care.o*net + 17332021-06-14 14:41:14.162329Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity Health Workers21-1094.00Community Health WorkersPromote health within a community by assisting individuals to adopt healthy behaviors. Serve as an advocate for the health needs of individuals by assisting community residents in effectively communicating with healthcare providers or social service agencies. Act as liaison or advocate and implement programs that promote, maintain, and improve individual and overall community health. May deliver health-related preventive services such as blood pressure, glaucoma, and hearing screenings. May collect data to help identify community health needs.o*net + 17342021-06-14 14:41:14.269361Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity and Social Service Specialists, All Other21-1099.00Community and Social Service Specialists, All OtherAll community and social service specialists not listed separately.o*net + 1982021-06-14 14:35:20.491437First-Line Supervisors of Law Enforcement Workers33-1010bls + 4952021-06-14 14:35:45.207569Supervisors of Protective Service Workers33-1000bls + 5692021-06-14 14:35:51.342069Protective Service Occupations33-0000bls + 7692021-06-14 14:36:29.614836Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsHealth Education Specialists21-1091Health Education Specialistsbls + 17302021-06-14 14:41:13.790333Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsHealth Education Specialists21-1091.00Health Education SpecialistsProvide and manage health education programs that help individuals, families, and their communities maximize and maintain healthy lifestyles. Use data to identify community needs prior to planning, implementing, monitoring, and evaluating programs designed to encourage healthy lifestyles, policies, and environments. May link health systems, health providers, insurers, and patients to address individual and population health needs. May serve as resource to assist individuals, other health professionals, or the community, and may administer fiscal resources for health education programs.o*net + 562021-06-14 14:35:07.918235Computer Support Specialists15-1230bls + 6572021-06-14 14:36:07.710870Computer and Mathematical OccupationsComputer OccupationsComputer Support SpecialistsComputer Network Support Specialists15-1231Computer Network Support Specialistsbls + 6622021-06-14 14:36:08.741135Computer and Mathematical OccupationsComputer OccupationsDatabase and Network Administrators and ArchitectsNetwork and Computer Systems Administrators15-1244Network and Computer Systems Administratorsbls + 24952021-06-14 14:43:50.07004115-1152.00 + 24962021-06-14 14:43:50.13504515-1142.00 + 452021-06-14 14:35:06.867237Accountants and Auditors13-2010bls + 472021-06-14 14:35:07.043237Budget Analysts13-2030bls + 482021-06-14 14:35:07.139237Credit Analysts13-2040bls + 502021-06-14 14:35:07.332235Financial Examiners13-2060bls + 522021-06-14 14:35:07.559241Tax Examiners, Collectors and Preparers, and Revenue Agents13-2080bls + 4652021-06-14 14:35:42.852499Financial Specialists13-2000bls + 6392021-06-14 14:36:04.418696Business and Financial Operations OccupationsFinancial SpecialistsAccountants and AuditorsAccountants and Auditors13-2011Accountants and Auditorsbls + 6422021-06-14 14:36:04.965996Business and Financial Operations OccupationsFinancial SpecialistsBudget AnalystsBudget Analysts13-2031Budget Analystsbls + 6432021-06-14 14:36:05.123825Business and Financial Operations OccupationsFinancial SpecialistsCredit AnalystsCredit Analysts13-2041Credit Analystsbls + 6482021-06-14 14:36:06.038318Business and Financial Operations OccupationsFinancial SpecialistsFinancial ExaminersFinancial Examiners13-2061Financial Examinersbls + 6512021-06-14 14:36:06.593319Business and Financial Operations OccupationsFinancial SpecialistsTax Examiners, Collectors and Preparers, and Revenue AgentsTax Examiners and Collectors, and Revenue Agents13-2081Tax Examiners and Collectors, and Revenue Agentsbls + 15402021-06-14 14:40:49.642083Business and Financial Operations OccupationsFinancial SpecialistsAccountants and AuditorsAccountants and Auditors13-2011.00Accountants and AuditorsExamine, analyze, and interpret accounting records to prepare financial statements, give advice, or audit and evaluate statements prepared by others. Install or advise on systems of recording costs or other financial and budgetary data.o*net + 15432021-06-14 14:40:50.038068Business and Financial Operations OccupationsFinancial SpecialistsBudget AnalystsBudget Analysts13-2031.00Budget AnalystsExamine budget estimates for completeness, accuracy, and conformance with procedures and regulations. Analyze budgeting and accounting reports.o*net + 15442021-06-14 14:40:50.204070Business and Financial Operations OccupationsFinancial SpecialistsCredit AnalystsCredit Analysts13-2041.00Credit AnalystsAnalyze credit data and financial statements of individuals or firms to determine the degree of risk involved in extending credit or lending money. Prepare reports with credit information for use in decisionmaking.o*net + 15492021-06-14 14:40:50.912825Business and Financial Operations OccupationsFinancial SpecialistsFinancial ExaminersFinancial Examiners13-2061.00Financial ExaminersEnforce or ensure compliance with laws and regulations governing financial and securities institutions and financial and real estate transactions. May examine, verify, or authenticate records.o*net + 15522021-06-14 14:40:51.315833Business and Financial Operations OccupationsFinancial SpecialistsTax Examiners, Collectors and Preparers, and Revenue AgentsTax Examiners and Collectors, and Revenue Agents13-2081.00Tax Examiners and Collectors, and Revenue AgentsDetermine tax liability or collect taxes from individuals or business firms according to prescribed laws and regulations.o*net + 24972021-06-14 14:43:51.66548413-2011.01 + 492021-06-14 14:35:07.238234Financial Analysts and Advisors13-2050bls + 6442021-06-14 14:36:05.295237Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsFinancial and Investment Analysts13-2051Financial and Investment Analystsbls + 6452021-06-14 14:36:05.513316Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsPersonal Financial Advisors13-2052Personal Financial Advisorsbls + 6462021-06-14 14:36:05.705317Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsInsurance Underwriters13-2053Insurance Underwritersbls + 6472021-06-14 14:36:05.891319Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsFinancial Risk Specialists13-2054Financial Risk Specialistsbls + 6522021-06-14 14:36:06.759316Business and Financial Operations OccupationsFinancial SpecialistsTax Examiners, Collectors and Preparers, and Revenue AgentsTax Preparers13-2082Tax Preparersbls + 72021-06-14 14:35:02.925162Administrative Services and Facilities Managers11-3010bls + 92021-06-14 14:35:03.143704Financial Managers11-3030bls + 4622021-06-14 14:35:42.625493Operations Specialties Managers11-3000bls + 5582021-06-14 14:35:50.542053Management Occupations11-0000bls + 5892021-06-14 14:35:54.363446Management OccupationsOperations Specialties ManagersAdministrative Services and Facilities ManagersAdministrative Services Managers11-3012Administrative Services Managersbls + 5902021-06-14 14:35:54.628490Management OccupationsOperations Specialties ManagersAdministrative Services and Facilities ManagersFacilities Managers11-3013Facilities Managersbls + 5922021-06-14 14:35:54.983491Management OccupationsOperations Specialties ManagersFinancial ManagersFinancial Managers11-3031Financial Managersbls + 14612021-06-14 14:40:39.457947Management OccupationsOperations Specialties ManagersFinancial ManagersFinancial Managers11-3031.00Financial ManagersPlan, direct, or coordinate accounting, investing, banking, insurance, securities, and other financial activities of a branch, office, or department of an establishment.o*net + 14622021-06-14 14:40:39.614946Management OccupationsOperations Specialties ManagersFinancial ManagersFinancial Managers11-3031.01Treasurers and ControllersDirect financial activities, such as planning, procurement, and investments for all or part of an organization.o*net + 24982021-06-14 14:43:52.84128811-3031.02 + 24992021-06-14 14:43:52.89028311-3011.00 + 6292021-06-14 14:36:02.251291Business and Financial Operations OccupationsBusiness Operations SpecialistsHuman Resources WorkersLabor Relations Specialists13-1075Labor Relations Specialistsbls + 12021-06-14 14:35:01.990157Chief Executives11-1010bls + 22021-06-14 14:35:02.204159General and Operations Managers11-1020bls + 42021-06-14 14:35:02.418159Advertising and Promotions Managers11-2010bls + 52021-06-14 14:35:02.654158Marketing and Sales Managers11-2020bls + 102021-06-14 14:35:03.233706Industrial Production Managers11-3050bls + 122021-06-14 14:35:03.440732Transportation, Storage, and Distribution Managers11-3070bls + 172021-06-14 14:35:03.912233Construction Managers11-9020bls + 272021-06-14 14:35:05.044822Social and Community Service Managers11-9150bls + 302021-06-14 14:35:05.343824Miscellaneous Managers11-9190bls + 352021-06-14 14:35:05.845819Cost Estimators13-1050bls + 2232021-06-14 14:35:22.498191First-Line Supervisors of Building and Grounds Cleaning and Maintenance Workers37-1010bls + 2272021-06-14 14:35:22.826184First-Line Supervisors of Entertainment and Recreation Workers39-1010bls + 2282021-06-14 14:35:22.898186First-Line Supervisors of Personal Service Workers39-1020bls + 4602021-06-14 14:35:42.438499Top Executives11-1000bls + 4612021-06-14 14:35:42.537495Advertising, Marketing, Promotions, Public Relations, and Sales Managers11-2000bls + 4632021-06-14 14:35:42.707494Other Management Occupations11-9000bls + 5032021-06-14 14:35:45.877570Supervisors of Building and Grounds Cleaning and Maintenance Workers37-1000bls + 5062021-06-14 14:35:46.075571Supervisors of Personal Care and Service Workers39-1000bls + 5712021-06-14 14:35:51.603070Building and Grounds Cleaning and Maintenance Occupations37-0000bls + 5722021-06-14 14:35:51.686075Personal Care and Service Occupations39-0000bls + 5812021-06-14 14:35:52.710074Management OccupationsTop ExecutivesChief ExecutivesChief Executives11-1011Chief Executivesbls + 5822021-06-14 14:35:52.927073Management OccupationsTop ExecutivesGeneral and Operations ManagersGeneral and Operations Managers11-1021General and Operations Managersbls + 5932021-06-14 14:35:55.170489Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051Industrial Production Managersbls + 5952021-06-14 14:35:55.536080Management OccupationsOperations Specialties ManagersTransportation, Storage, and Distribution ManagersTransportation, Storage, and Distribution Managers11-3071Transportation, Storage, and Distribution Managersbls + 6002021-06-14 14:35:56.404622Management OccupationsOther Management OccupationsConstruction ManagersConstruction Managers11-9021Construction Managersbls + 6142021-06-14 14:35:59.331417Management OccupationsOther Management OccupationsSocial and Community Service ManagersSocial and Community Service Managers11-9151Social and Community Service Managersbls + 6182021-06-14 14:36:00.067410Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199Managers, All Otherbls + 6262021-06-14 14:36:01.677933Business and Financial Operations OccupationsBusiness Operations SpecialistsCost EstimatorsCost Estimators13-1051Cost Estimatorsbls + 10242021-06-14 14:37:26.947314Building and Grounds Cleaning and Maintenance OccupationsSupervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Housekeeping and Janitorial Workers37-1011First-Line Supervisors of Housekeeping and Janitorial Workersbls + 10362021-06-14 14:37:28.865937Personal Care and Service OccupationsSupervisors of Personal Care and Service WorkersFirst-Line Supervisors of Personal Service WorkersFirst-Line Supervisors of Personal Service Workers39-1022First-Line Supervisors of Personal Service Workersbls + 14482021-06-14 14:40:37.016423Management OccupationsTop ExecutivesChief ExecutivesChief Executives11-1011.00Chief ExecutivesDetermine and formulate policies and provide overall direction of companies or private and public sector organizations within guidelines set up by a board of directors or similar governing body. Plan, direct, or coordinate operational activities at the highest level of management with the help of subordinate executives and staff managers.o*net + 14502021-06-14 14:40:37.598961Management OccupationsTop ExecutivesGeneral and Operations ManagersGeneral and Operations Managers11-1021.00General and Operations ManagersPlan, direct, or coordinate the operations of public or private sector organizations, overseeing multiple departments or locations. Duties and responsibilities include formulating policies, managing daily operations, and planning the use of materials and human resources, but are too diverse and general in nature to be classified in any one functional area of management or administration, such as personnel, purchasing, or administrative services. Usually manage through subordinate supervisors. Excludes First-Line Supervisors.o*net + 14522021-06-14 14:40:37.912963Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersAdvertising and Promotions ManagersAdvertising and Promotions Managers11-2011.00Advertising and Promotions ManagersPlan, direct, or coordinate advertising policies and programs or produce collateral materials, such as posters, contests, coupons, or giveaways, to create extra interest in the purchase of a product or service for a department, an entire organization, or on an account basis.o*net + 14532021-06-14 14:40:38.063017Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersMarketing Managers11-2021.00Marketing ManagersPlan, direct, or coordinate marketing policies and programs, such as determining the demand for products and services offered by a firm and its competitors, and identify potential customers. Develop pricing strategies with the goal of maximizing the firm's profits or share of the market while ensuring the firm's customers are satisfied. Oversee product development or monitor trends that indicate the need for new products and services.o*net + 14542021-06-14 14:40:38.225940Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersSales Managers11-2022.00Sales ManagersPlan, direct, or coordinate the actual distribution or movement of a product or service to the customer. Coordinate sales distribution by establishing sales territories, quotas, and goals and establish training programs for sales representatives. Analyze sales statistics gathered by staff to determine sales potential and inventory requirements and monitor the preferences of customers.o*net + 14572021-06-14 14:40:38.739941Management OccupationsOperations Specialties ManagersAdministrative Services and Facilities ManagersAdministrative Services Managers11-3012.00Administrative Services ManagersPlan, direct, or coordinate one or more administrative services of an organization, such as records and information management, mail distribution, and other office support services.o*net + 14642021-06-14 14:40:39.923972Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.00Industrial Production ManagersPlan, direct, or coordinate the work activities and resources necessary for manufacturing products in accordance with cost, quality, and quantity specifications.o*net + 14712021-06-14 14:40:40.839886Management OccupationsOperations Specialties ManagersTransportation, Storage, and Distribution ManagersTransportation, Storage, and Distribution Managers11-3071.00Transportation, Storage, and Distribution ManagersPlan, direct, or coordinate transportation, storage, or distribution activities in accordance with organizational policies and applicable government laws or regulations. Includes logistics managers.o*net + 14772021-06-14 14:40:41.695748Management OccupationsOther Management OccupationsConstruction ManagersConstruction Managers11-9021.00Construction ManagersPlan, direct, or coordinate, usually through subordinate supervisory personnel, activities concerned with the construction and maintenance of structures, facilities, and systems. Participate in the conceptual development of a construction project and oversee its organization, scheduling, budgeting, and implementation. Includes managers in specialized construction fields, such as carpentry or plumbing.o*net + 14942021-06-14 14:40:43.978215Management OccupationsOther Management OccupationsSocial and Community Service ManagersSocial and Community Service Managers11-9151.00Social and Community Service ManagersPlan, direct, or coordinate the activities of a social service program or community outreach organization. Oversee the program or organization's budget and policies regarding participant involvement, program requirements, and benefits. Work may involve directing social workers, counselors, or probation officers.o*net + 15002021-06-14 14:40:44.813290Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.00Managers, All OtherAll managers not listed separately.o*net + 15202021-06-14 14:40:47.239188Business and Financial Operations OccupationsBusiness Operations SpecialistsCost EstimatorsCost Estimators13-1051.00Cost EstimatorsPrepare cost estimates for product manufacturing, construction projects, or services to aid management in bidding on or determining price of product or service. May specialize according to particular service performed or type of product manufactured.o*net + 15282021-06-14 14:40:48.196409Business and Financial Operations OccupationsBusiness Operations SpecialistsManagement AnalystsManagement Analysts13-1111.00Management AnalystsConduct organizational studies and evaluations, design systems and procedures, conduct work simplification and measurement studies, and prepare operations and procedures manuals to assist management in operating more efficiently and effectively. Includes program analysts and management consultants.o*net + 15332021-06-14 14:40:48.802524Business and Financial Operations OccupationsBusiness Operations SpecialistsMarket Research Analysts and Marketing SpecialistsMarket Research Analysts and Marketing Specialists13-1161.00Market Research Analysts and Marketing SpecialistsResearch conditions in local, regional, national, or online markets. Gather information to determine potential sales of a product or service, or plan a marketing or advertising campaign. May gather information on competitors, prices, sales, and methods of marketing and distribution. May employ search marketing tactics, analyze web metrics, and develop recommendations to increase search engine ranking and visibility to target markets.o*net + 20212021-06-14 14:41:47.909544Building and Grounds Cleaning and Maintenance OccupationsSupervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Housekeeping and Janitorial Workers37-1011.00First-Line Supervisors of Housekeeping and Janitorial WorkersDirectly supervise and coordinate work activities of cleaning personnel in hotels, hospitals, offices, and other establishments.o*net + 20332021-06-14 14:41:49.217526Personal Care and Service OccupationsSupervisors of Personal Care and Service WorkersFirst-Line Supervisors of Personal Service WorkersFirst-Line Supervisors of Personal Service Workers39-1022.00First-Line Supervisors of Personal Service WorkersSupervise and coordinate activities of personal service workers.o*net + 25002021-06-14 14:43:55.98697339-1011 + 25012021-06-14 14:43:56.07097539-1011.00 + 752021-06-14 14:35:09.714658Environmental Engineers17-2080bls + 762021-06-14 14:35:09.795693Industrial Engineers, Including Health and Safety17-2110bls + 6872021-06-14 14:36:13.418391Architecture and Engineering OccupationsEngineersEnvironmental EngineersEnvironmental Engineers17-2081Environmental Engineersbls + 6882021-06-14 14:36:13.602395Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyHealth and Safety Engineers, Except Mining Safety Engineers and Inspectors17-2111Health and Safety Engineers, Except Mining Safety Engineers and Inspectorsbls + 6892021-06-14 14:36:13.779782Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyIndustrial Engineers17-2112Industrial Engineersbls + 16112021-06-14 14:40:58.932364Architecture and Engineering OccupationsEngineersEnvironmental EngineersEnvironmental Engineers17-2081.00Environmental EngineersResearch, design, plan, or perform engineering duties in the prevention, control, and remediation of environmental hazards using various engineering disciplines. Work may include waste treatment, site remediation, or pollution control technology.o*net + 16122021-06-14 14:40:59.046332Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyHealth and Safety Engineers, Except Mining Safety Engineers and Inspectors17-2111.00Health and Safety Engineers, Except Mining Safety Engineers and InspectorsPromote worksite or product safety by applying knowledge of industrial processes, mechanics, chemistry, psychology, and industrial health and safety laws. Includes industrial product safety engineers.o*net + 16132021-06-14 14:40:59.177095Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyHealth and Safety Engineers, Except Mining Safety Engineers and Inspectors17-2111.02Fire-Prevention and Protection EngineersResearch causes of fires, determine fire protection methods, and design or recommend materials or equipment such as structural components or fire-detection equipment to assist organizations in safeguarding life and property against fire, explosion, and related hazards.o*net + 16142021-06-14 14:40:59.293692Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyIndustrial Engineers17-2112.00Industrial EngineersDesign, develop, test, and evaluate integrated systems for managing industrial production processes, including human work factors, quality control, inventory control, logistics and material flow, cost analysis, and production coordination.o*net + 16152021-06-14 14:40:59.405691Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyIndustrial Engineers17-2112.01Human Factors Engineers and ErgonomistsDesign objects, facilities, and environments to optimize human well-being and overall system performance, applying theory, principles, and data regarding the relationship between humans and respective technology. Investigate and analyze characteristics of human behavior and performance as it relates to the use of technology.o*net + 25022021-06-14 14:43:57.84826017-2081.01 + 25032021-06-14 14:43:57.89983417-2111.01 + 25042021-06-14 14:43:57.95580017-2111.03 + 18062021-06-14 14:41:22.692011Educational Instruction and Library OccupationsLibrarians, Curators, and ArchivistsLibrary TechniciansLibrary Technicians25-4031.00Library TechniciansAssist librarians by helping readers in the use of library catalogs, databases, and indexes to locate books and other materials; and by answering questions that require only brief consultation of standard reference. Compile records; sort and shelve books or other media; remove or repair damaged books or other media; register patrons; and check materials in and out of the circulation process. Replace materials in shelving area (stacks) or files. Includes bookmobile drivers who assist with providing services in mobile libraries.o*net + 25052021-06-14 14:43:59.72127825-4021.00 + 1122021-06-14 14:35:12.758535Counselors21-1010bls + 1132021-06-14 14:35:12.837531Social Workers21-1020bls + 1682021-06-14 14:35:17.815821Optometrists29-1040bls + 1772021-06-14 14:35:18.548440Nurse Practitioners29-1170bls + 7592021-06-14 14:36:27.766207Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsSubstance Abuse and Behavioral Disorder Counselors21-1011Substance Abuse and Behavioral Disorder Counselorsbls + 7622021-06-14 14:36:28.298017Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsMental Health Counselors21-1014Mental Health Counselorsbls + 7662021-06-14 14:36:29.050838Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsSocial WorkersHealthcare Social Workers21-1022Healthcare Social Workersbls + 9002021-06-14 14:36:55.262783Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersOptometristsOptometrists29-1041Optometristsbls + 9162021-06-14 14:36:57.936515Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersNurse PractitionersNurse Practitioners29-1171Nurse Practitionersbls + 17202021-06-14 14:41:12.617778Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsSubstance Abuse and Behavioral Disorder Counselors21-1011.00Substance Abuse and Behavioral Disorder CounselorsCounsel and advise individuals with alcohol, tobacco, drug, or other problems, such as gambling and eating disorders. May counsel individuals, families, or groups or engage in prevention programs.o*net + 17232021-06-14 14:41:13.027799Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsMental Health Counselors21-1014.00Mental Health CounselorsCounsel and advise individuals and groups to promote optimum mental and emotional health, with an emphasis on prevention. May help individuals deal with a broad range of mental health issues, such as those associated with addictions and substance abuse; family, parenting, and marital problems; stress management; self-esteem; or aging.o*net + 17272021-06-14 14:41:13.464799Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsSocial WorkersHealthcare Social Workers21-1022.00Healthcare Social WorkersProvide individuals, families, and groups with the psychosocial support needed to cope with chronic, acute, or terminal illnesses. Services include advising family caregivers. Provide patients with information and counseling, and make referrals for other services. May also provide case and care management or interventions designed to promote health, prevent disease, and address barriers to access to healthcare.o*net + 18662021-06-14 14:41:30.006598Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersOptometristsOptometrists29-1041.00OptometristsDiagnose, manage, and treat conditions and diseases of the human eye and visual system. Examine eyes and visual system, diagnose problems or impairments, prescribe corrective lenses, and provide treatment. May prescribe therapeutic drugs to treat specific eye conditions.o*net + 18902021-06-14 14:41:32.478173Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersNurse PractitionersNurse Practitioners29-1171.00Nurse PractitionersDiagnose and treat acute, episodic, or chronic illness, independently or as part of a healthcare team. May focus on health promotion and disease prevention. May order, perform, or interpret diagnostic tests such as lab work and x rays. May prescribe medication. Must be registered nurses who have specialized graduate education.o*net + 1812021-06-14 14:35:18.851438Miscellaneous Healthcare Diagnosing or Treating Practitioners29-1290bls + 9362021-06-14 14:37:02.215532Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersMiscellaneous Healthcare Diagnosing or Treating PractitionersDental Hygienists29-1292Dental Hygienistsbls + 25062021-06-14 14:44:00.61533229-2021.00 + 1972021-06-14 14:35:20.387439Miscellaneous Healthcare Support Occupations31-9090bls + 4942021-06-14 14:35:45.136575Other Healthcare Support Occupations31-9000bls + 5682021-06-14 14:35:51.271071Healthcare Support Occupations31-0000bls + 9762021-06-14 14:37:08.814104Healthcare Support OccupationsOther Healthcare Support OccupationsMiscellaneous Healthcare Support OccupationsMedical Assistants31-9092Medical Assistantsbls + 19662021-06-14 14:41:41.634872Healthcare Support OccupationsOther Healthcare Support OccupationsMiscellaneous Healthcare Support OccupationsMedical Assistants31-9092.00Medical AssistantsPerform administrative and certain clinical duties under the direction of a physician. Administrative duties may include scheduling appointments, maintaining medical records, billing, and coding information for insurance purposes. Clinical duties may include taking and recording vital signs and medical histories, preparing patients for examination, drawing blood, and administering medications as directed by physician.o*net + 322021-06-14 14:35:05.566821Buyers and Purchasing Agents13-1020bls + 632021-06-14 14:35:08.694119Statisticians15-2040bls + 972021-06-14 14:35:11.521334Economists19-3010bls + 1082021-06-14 14:35:12.369837Social Science Research Assistants19-4060bls + 2042021-06-14 14:35:21.006439Detectives and Criminal Investigators33-3020bls + 4672021-06-14 14:35:42.988496Mathematical Science Occupations15-2000bls + 4732021-06-14 14:35:43.476026Social Scientists and Related Workers19-3000bls + 4742021-06-14 14:35:43.581022Life, Physical, and Social Science Technicians19-4000bls + 4972021-06-14 14:35:45.356570Law Enforcement Workers33-3000bls + 5622021-06-14 14:35:50.842076Life, Physical, and Social Science Occupations19-0000bls + 6202021-06-14 14:36:00.446412Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsBuyers and Purchasing Agents, Farm Products13-1021Buyers and Purchasing Agents, Farm Productsbls + 6212021-06-14 14:36:00.659446Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsWholesale and Retail Buyers, Except Farm Products13-1022Wholesale and Retail Buyers, Except Farm Productsbls + 6222021-06-14 14:36:00.872414Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsPurchasing Agents, Except Wholesale, Retail, and Farm Products13-1023Purchasing Agents, Except Wholesale, Retail, and Farm Productsbls + 6722021-06-14 14:36:10.658688Computer and Mathematical OccupationsMathematical Science OccupationsStatisticiansStatisticians15-2041Statisticiansbls + 7322021-06-14 14:36:22.064780Life, Physical, and Social Science OccupationsSocial Scientists and Related WorkersEconomistsEconomists19-3011Economistsbls + 7532021-06-14 14:36:26.592098Life, Physical, and Social Science OccupationsLife, Physical, and Social Science TechniciansSocial Science Research AssistantsSocial Science Research Assistants19-4061Social Science Research Assistantsbls + 15022021-06-14 14:40:45.089290Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.02Compliance ManagersPlan, direct, or coordinate activities of an organization to ensure compliance with ethical or regulatory standards.o*net + 15082021-06-14 14:40:45.821388Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsBuyers and Purchasing Agents, Farm Products13-1021.00Buyers and Purchasing Agents, Farm ProductsPurchase farm products either for further processing or resale. Includes tree farm contractors, grain brokers and market operators, grain buyers, and tobacco buyers. May negotiate contracts.o*net + 15092021-06-14 14:40:45.941385Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsWholesale and Retail Buyers, Except Farm Products13-1022.00Wholesale and Retail Buyers, Except Farm ProductsBuy merchandise or commodities, other than farm products, for resale to consumers at the wholesale or retail level, including both durable and nondurable goods. Analyze past buying trends, sales records, price, and quality of merchandise to determine value and yield. Select, order, and authorize payment for merchandise according to contractual agreements. May conduct meetings with sales personnel and introduce new products. May negotiate contracts. Includes assistant wholesale and retail buyers of nonfarm products.o*net + 15102021-06-14 14:40:46.053383Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsPurchasing Agents, Except Wholesale, Retail, and Farm Products13-1023.00Purchasing Agents, Except Wholesale, Retail, and Farm ProductsPurchase machinery, equipment, tools, parts, supplies, or services necessary for the operation of an establishment. Purchase raw or semifinished materials for manufacturing. May negotiate contracts.o*net + 15882021-06-14 14:40:56.123269Computer and Mathematical OccupationsMathematical Science OccupationsStatisticiansStatisticians15-2041.00StatisticiansDevelop or apply mathematical or statistical theory and methods to collect, organize, interpret, and summarize numerical data to provide usable information. May specialize in fields such as biostatistics, agricultural statistics, business statistics, or economic statistics. Includes mathematical and survey statisticians.o*net + 16852021-06-14 14:41:08.473329Life, Physical, and Social Science OccupationsSocial Scientists and Related WorkersEconomistsEconomists19-3011.00EconomistsConduct research, prepare reports, or formulate plans to address economic problems related to the production and distribution of goods and services or monetary and fiscal policy. May collect and process economic and statistical data using sampling techniques and econometric methods.o*net + 17122021-06-14 14:41:11.523130Life, Physical, and Social Science OccupationsLife, Physical, and Social Science TechniciansSocial Science Research AssistantsSocial Science Research Assistants19-4061.00Social Science Research AssistantsAssist social scientists in laboratory, survey, and other social science research. May help prepare findings for publication and assist in laboratory analysis, quality control, or data management.o*net + 25072021-06-14 14:44:01.73575013-2011.02 + 372021-06-14 14:35:06.035826Logisticians and Project Management Specialists13-1080bls + 412021-06-14 14:35:06.479825Compensation, Benefits, and Job Analysis Specialists13-1140bls + 422021-06-14 14:35:06.590824Training and Development Specialists13-1150bls + 442021-06-14 14:35:06.771825Miscellaneous Business Operations Specialists13-1190bls + 6302021-06-14 14:36:02.433134Business and Financial Operations OccupationsBusiness Operations SpecialistsLogisticians and Project Management SpecialistsLogisticians13-1081Logisticiansbls + 6312021-06-14 14:36:02.643140Business and Financial Operations OccupationsBusiness Operations SpecialistsLogisticians and Project Management SpecialistsProject Management Specialists13-1082Project Management Specialistsbls + 6352021-06-14 14:36:03.703134Business and Financial Operations OccupationsBusiness Operations SpecialistsCompensation, Benefits, and Job Analysis SpecialistsCompensation, Benefits, and Job Analysis Specialists13-1141Compensation, Benefits, and Job Analysis Specialistsbls + 6362021-06-14 14:36:03.876134Business and Financial Operations OccupationsBusiness Operations SpecialistsTraining and Development SpecialistsTraining and Development Specialists13-1151Training and Development Specialistsbls + 25082021-06-14 14:44:02.63944113-1191 + 622021-06-14 14:35:08.608117Operations Research Analysts15-2030bls + 6712021-06-14 14:36:10.458686Computer and Mathematical OccupationsMathematical Science OccupationsOperations Research AnalystsOperations Research Analysts15-2031Operations Research Analystsbls + 15872021-06-14 14:40:55.994729Computer and Mathematical OccupationsMathematical Science OccupationsOperations Research AnalystsOperations Research Analysts15-2031.00Operations Research AnalystsFormulate and apply mathematical modeling and other optimizing methods to develop and interpret information that assists management with decisionmaking, policy formulation, or other managerial functions. May collect and analyze data and develop decision support software, services, or products. May develop and supply optimal time, cost, or logistics networks for program evaluation, review, or implementation.o*net + 82021-06-14 14:35:03.040165Computer and Information Systems Managers11-3020bls + 112021-06-14 14:35:03.322699Purchasing Managers11-3060bls + 132021-06-14 14:35:03.535729Compensation and Benefits Managers11-3110bls + 232021-06-14 14:35:04.557822Medical and Health Services Managers11-9110bls + 5912021-06-14 14:35:54.806497Management OccupationsOperations Specialties ManagersComputer and Information Systems ManagersComputer and Information Systems Managers11-3021Computer and Information Systems Managersbls + 5942021-06-14 14:35:55.329083Management OccupationsOperations Specialties ManagersPurchasing ManagersPurchasing Managers11-3061Purchasing Managersbls + 5962021-06-14 14:35:55.716082Management OccupationsOperations Specialties ManagersCompensation and Benefits ManagersCompensation and Benefits Managers11-3111Compensation and Benefits Managersbls + 6102021-06-14 14:35:58.473812Management OccupationsOther Management OccupationsMedical and Health Services ManagersMedical and Health Services Managers11-9111Medical and Health Services Managersbls + 14492021-06-14 14:40:37.350957Management OccupationsTop ExecutivesChief ExecutivesChief Executives11-1011.03Chief Sustainability OfficersCommunicate and coordinate with management, shareholders, customers, and employees to address sustainability issues. Enact or oversee a corporate sustainability strategy.o*net + 14602021-06-14 14:40:39.270941Management OccupationsOperations Specialties ManagersComputer and Information Systems ManagersComputer and Information Systems Managers11-3021.00Computer and Information Systems ManagersPlan, direct, or coordinate activities in such fields as electronic data processing, information systems, systems analysis, and computer programming.o*net + 14652021-06-14 14:40:40.047942Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.01Quality Control Systems ManagersPlan, direct, or coordinate quality assurance programs. Formulate quality control policies and control quality of laboratory and production efforts.o*net + 14662021-06-14 14:40:40.185978Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.02Geothermal Production ManagersManage operations at geothermal power generation facilities. Maintain and monitor geothermal plant equipment for efficient and safe plant operations.o*net + 14672021-06-14 14:40:40.324980Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.03Biofuels Production ManagersManage biofuels production and plant operations. Collect and process information on plant production and performance, diagnose problems, and design corrective procedures.o*net + 14682021-06-14 14:40:40.469974Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.04Biomass Power Plant ManagersManage operations at biomass power generation facilities. Direct work activities at plant, including supervision of operations and maintenance staff.o*net + 14692021-06-14 14:40:40.580979Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.06Hydroelectric Production ManagersManage operations at hydroelectric power generation facilities. Maintain and monitor hydroelectric plant equipment for efficient and safe plant operations.o*net + 14702021-06-14 14:40:40.709971Management OccupationsOperations Specialties ManagersPurchasing ManagersPurchasing Managers11-3061.00Purchasing ManagersPlan, direct, or coordinate the activities of buyers, purchasing officers, and related workers involved in purchasing materials, products, and services. Includes wholesale or retail trade merchandising managers and procurement managers.o*net + 14732021-06-14 14:40:41.097886Management OccupationsOperations Specialties ManagersCompensation and Benefits ManagersCompensation and Benefits Managers11-3111.00Compensation and Benefits ManagersPlan, direct, or coordinate compensation and benefits activities of an organization.o*net + 14882021-06-14 14:40:43.219560Management OccupationsOther Management OccupationsMedical and Health Services ManagersMedical and Health Services Managers11-9111.00Medical and Health Services ManagersPlan, direct, or coordinate medical and health services in hospitals, clinics, managed care organizations, public health agencies, or similar organizations.o*net + 15012021-06-14 14:40:44.948290Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.01Regulatory Affairs ManagersPlan, direct, or coordinate production activities of an organization to ensure compliance with regulations and standard operating procedures.o*net + 15032021-06-14 14:40:45.212350Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.08Loss Prevention ManagersPlan and direct policies, procedures, or systems to prevent the loss of assets. Determine risk exposure or potential liability, and develop risk control measures.o*net + 15042021-06-14 14:40:45.343419Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.09Wind Energy Operations ManagersManage wind field operations, including personnel, maintenance activities, financial activities, and planning.o*net + 15052021-06-14 14:40:45.467384Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.10Wind Energy Development ManagersLead or manage the development and evaluation of potential wind energy business opportunities, including environmental studies, permitting, and proposals. May also manage construction of projects.o*net + 15062021-06-14 14:40:45.578389Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.11Brownfield Redevelopment Specialists and Site ManagersPlan and direct cleanup and redevelopment of contaminated properties for reuse. Does not include properties sufficiently contaminated to qualify as Superfund sites.o*net + 25092021-06-14 14:44:03.79464011-3051.05 + 25102021-06-14 14:44:03.85364811-3071.01 + 25112021-06-14 14:44:03.89661811-3071.02 + 25122021-06-14 14:44:03.93961411-3071.03 + 25132021-06-14 14:44:03.99163711-9199.03 + 25142021-06-14 14:44:04.04161511-9199.04 + 25152021-06-14 14:44:04.08564511-9199.07 + 142021-06-14 14:35:03.638264Human Resources Managers11-3120bls + 152021-06-14 14:35:03.736177Training and Development Managers11-3130bls + 5972021-06-14 14:35:55.877109Management OccupationsOperations Specialties ManagersHuman Resources ManagersHuman Resources Managers11-3121Human Resources Managersbls + 5982021-06-14 14:35:56.044078Management OccupationsOperations Specialties ManagersTraining and Development ManagersTraining and Development Managers11-3131Training and Development Managersbls + 14742021-06-14 14:40:41.211889Management OccupationsOperations Specialties ManagersHuman Resources ManagersHuman Resources Managers11-3121.00Human Resources ManagersPlan, direct, or coordinate human resources activities and staff of an organization.o*net + 14752021-06-14 14:40:41.373746Management OccupationsOperations Specialties ManagersTraining and Development ManagersTraining and Development Managers11-3131.00Training and Development ManagersPlan, direct, or coordinate the training and development activities and staff of an organization.o*net + 1872021-06-14 14:35:19.503443Medical Records Specialists29-2070bls + 1882021-06-14 14:35:19.617443Opticians, Dispensing29-2080bls + 4902021-06-14 14:35:44.851571Health Technologists and Technicians29-2000bls + 9552021-06-14 14:37:05.583679Healthcare Practitioners and Technical OccupationsHealth Technologists and TechniciansMedical Records SpecialistsMedical Records Specialists29-2072Medical Records Specialistsbls + 9562021-06-14 14:37:05.727699Healthcare Practitioners and Technical OccupationsHealth Technologists and TechniciansOpticians, DispensingOpticians, Dispensing29-2081Opticians, Dispensingbls + 19422021-06-14 14:41:38.860920Healthcare Practitioners and Technical OccupationsHealth Technologists and TechniciansOpticians, DispensingOpticians, Dispensing29-2081.00Opticians, DispensingDesign, measure, fit, and adapt lenses and frames for client according to written optical prescription or specification. Assist client with inserting, removing, and caring for contact lenses. Assist client with selecting frames. Measure customer for size of eyeglasses and coordinate frames with facial and eye measurements and optical prescription. Prepare work order for optical laboratory containing instructions for grinding and mounting lenses in frames. Verify exactness of finished lens spectacles. Adjust frame and lens position to fit client. May shape or reshape frames. Includes contact lens opticians.o*net + 25162021-06-14 14:44:11.42995129-2071.00 + + + 12021-06-14 14:43:13.3675232021-06-14 14:43:13.367523Category.NET Framework + 22021-06-14 14:43:13.6485222021-06-14 14:43:13.648522Keyword.NET Framework + 32021-06-14 14:43:13.7565232021-06-14 14:43:13.756523KeywordADO.NET + 42021-06-14 14:43:13.8495342021-06-14 14:43:13.849534KeywordLanguage Integrated Query (LINQ) + 52021-06-14 14:43:13.9425252021-06-14 14:43:13.942525KeywordWCF Data Services + 62021-06-14 14:43:14.0225262021-06-14 14:43:14.022526KeywordXML + 72021-06-14 14:43:14.1525222021-06-14 14:43:14.152522Alignment.NET Framework2021-06-14 14:43:14.152522 + 82021-06-14 14:43:14.2415212021-06-14 14:43:14.241521AuthorWestern Governors University + 92021-06-14 14:43:14.6805212021-06-14 14:43:14.680521KeywordWindows Communication Foundation (WCF) + 102021-06-14 14:43:15.0785242021-06-14 14:43:15.078524KeywordASP.NET + 112021-06-14 14:43:15.5400272021-06-14 14:43:15.540027KeywordWindows Presentation Foundation (WPF) or Windows Forms + 122021-06-14 14:43:15.8027762021-06-14 14:43:15.802776Category3D Modeling + 132021-06-14 14:43:15.8717762021-06-14 14:43:15.871776Keyword3D Modeling + 142021-06-14 14:43:15.9279492021-06-14 14:43:15.927949KeywordDesignCAD + 152021-06-14 14:43:15.9809432021-06-14 14:43:15.980943KeywordAutodesk 3D Studio Design + 162021-06-14 14:43:16.0329482021-06-14 14:43:16.032948Keyword3ds MAX + 172021-06-14 14:43:16.0839472021-06-14 14:43:16.083947KeywordBlender + 182021-06-14 14:43:16.1289482021-06-14 14:43:16.128948KeywordLightWave + 192021-06-14 14:43:16.3962812021-06-14 14:43:16.396281Alignment3D Modeling2021-06-14 14:43:16.396281 + 202021-06-14 14:43:17.1353722021-06-14 14:43:17.135372CategoryAbstract Data Types + 212021-06-14 14:43:17.1958562021-06-14 14:43:17.195856KeywordAbstract Data Types + 222021-06-14 14:43:17.2488512021-06-14 14:43:17.248851AlignmentAbstract Data Types2021-06-14 14:43:17.248851 + 232021-06-14 14:43:17.4140492021-06-14 14:43:17.414049CategoryAcademic Accommodation Plans + 242021-06-14 14:43:17.4700492021-06-14 14:43:17.470049KeywordAcademic Accommodation Plans + 252021-06-14 14:43:17.5320522021-06-14 14:43:17.532052KeywordAccommodations + 262021-06-14 14:43:17.5820532021-06-14 14:43:17.582053StandardATD.Pers.CE + 272021-06-14 14:43:17.6310482021-06-14 14:43:17.631048StandardATD.Prof.ID + 282021-06-14 14:43:17.6800482021-06-14 14:43:17.680048StandardATD.Prof.TA + 292021-06-14 14:43:17.7340492021-06-14 14:43:17.734049StandardATD.Prof.TDF + 302021-06-14 14:43:17.7820862021-06-14 14:43:17.782086StandardISTE.Coach.C.3a + 312021-06-14 14:43:17.8370532021-06-14 14:43:17.837053StandardISTE.Coach.CA.1a + 322021-06-14 14:43:17.8880552021-06-14 14:43:17.888055StandardISTE.Coach.CA.1c + 332021-06-14 14:43:17.9350472021-06-14 14:43:17.935047StandardISTE.Coach.CL.2c + 342021-06-14 14:43:17.9870702021-06-14 14:43:17.987070StandardISTE.Coach.LD.4c + 352021-06-14 14:43:18.0290512021-06-14 14:43:18.029051StandardISTE.Coach.PLF.5a + 362021-06-14 14:43:18.0720502021-06-14 14:43:18.072050StandardISTE.Coach.PLF.5b + 372021-06-14 14:43:18.2870502021-06-14 14:43:18.287050AlignmentAcademic Accommodation Plans2021-06-14 14:43:18.287050 + 382021-06-14 14:43:19.0360432021-06-14 14:43:19.036043StandardISTE.Coach.C.3b + 392021-06-14 14:43:19.0870362021-06-14 14:43:19.087036StandardISTE.Coach.C.3d + 402021-06-14 14:43:20.0110372021-06-14 14:43:20.011037StandardATD.Org.CBP + 412021-06-14 14:43:20.0690402021-06-14 14:43:20.069040StandardATD.Org.ODC + 422021-06-14 14:43:20.1140362021-06-14 14:43:20.114036StandardATD.Pers.CL + 432021-06-14 14:43:20.1550672021-06-14 14:43:20.155067StandardATD.Pers.PM + 442021-06-14 14:43:20.2130352021-06-14 14:43:20.213035StandardISTE.Coach.CA.1b + 452021-06-14 14:43:21.6196682021-06-14 14:43:21.619668StandardATD.Prof.LS + 462021-06-14 14:43:22.7102512021-06-14 14:43:22.710251StandardISTE.Coach.LD.4b + 472021-06-14 14:43:24.7280312021-06-14 14:43:24.728031CategoryAcademic Advising + 482021-06-14 14:43:24.7791422021-06-14 14:43:24.779142KeywordAcademic Advising + 492021-06-14 14:43:24.8220642021-06-14 14:43:24.822064KeywordAcademic Counseling + 502021-06-14 14:43:24.8970642021-06-14 14:43:24.897064AlignmentAcademic Advising2021-06-14 14:43:24.897064 + 512021-06-14 14:43:25.5979042021-06-14 14:43:25.597904StandardISTE.Coach.LD.4a + 522021-06-14 14:43:25.6439062021-06-14 14:43:25.643906StandardISTE.Coach.LD.4d + 532021-06-14 14:43:26.8718152021-06-14 14:43:26.871815StandardISTE.Coach.DCA.7a + 542021-06-14 14:43:26.9108232021-06-14 14:43:26.910823StandardISTE.Coach.DCA.7b + 552021-06-14 14:43:26.9537962021-06-14 14:43:26.953796StandardISTE.Coach.DCA.7c + 562021-06-14 14:43:27.0008232021-06-14 14:43:27.000823StandardISTE.Coach.DCA.7d + 572021-06-14 14:43:29.6223382021-06-14 14:43:29.622338CategoryAcademic Tenacity + 582021-06-14 14:43:29.6963392021-06-14 14:43:29.696339KeywordAcademic Tenacity + 592021-06-14 14:43:29.7403382021-06-14 14:43:29.740338KeywordAcademic Achievement + 602021-06-14 14:43:29.7843392021-06-14 14:43:29.784339KeywordAcademic Standards + 612021-06-14 14:43:29.8398692021-06-14 14:43:29.838861KeywordAcademic Integrity + 622021-06-14 14:43:29.8968942021-06-14 14:43:29.896894KeywordPersistence + 632021-06-14 14:43:29.9498622021-06-14 14:43:29.949862StandardATD.Org.FR + 642021-06-14 14:43:29.9988642021-06-14 14:43:29.998864StandardATD.Pers.LL + 652021-06-14 14:43:30.0618632021-06-14 14:43:30.061863StandardISTE.Coach.CL.2a + 662021-06-14 14:43:30.1238642021-06-14 14:43:30.123864StandardISTE.Coach.CL.2b + 672021-06-14 14:43:30.1918692021-06-14 14:43:30.191869StandardISTE.Coach.DDM.6c + 682021-06-14 14:43:30.2698632021-06-14 14:43:30.269863StandardISTE.Coach.PLF.5c + 692021-06-14 14:43:30.3468652021-06-14 14:43:30.346865StandardCEC_2.2 + 702021-06-14 14:43:30.4158632021-06-14 14:43:30.415863StandardCEC_4.1 + 712021-06-14 14:43:30.4678612021-06-14 14:43:30.467861StandardCEC_6.2 + 722021-06-14 14:43:30.5488632021-06-14 14:43:30.548863StandardCEC_6.3 + 732021-06-14 14:43:30.6188672021-06-14 14:43:30.618867StandardUETS_5 + 742021-06-14 14:43:31.2513042021-06-14 14:43:31.251304KeywordSEL: Executive Function + 752021-06-14 14:43:31.3093752021-06-14 14:43:31.309375KeywordBeing + 762021-06-14 14:43:32.2025522021-06-14 14:43:32.202552StandardISTE.Coach.DDM.6a + 772021-06-14 14:43:32.2545592021-06-14 14:43:32.254559StandardISTE.Coach.DDM.6b + 782021-06-14 14:43:32.6858052021-06-14 14:43:32.685805KeywordThinking + 792021-06-14 14:43:33.1188072021-06-14 14:43:33.118807StandardATD.Pers.CA + 802021-06-14 14:43:35.4991882021-06-14 14:43:35.499188StandardCASEL + 812021-06-14 14:43:36.4211872021-06-14 14:43:36.421187CategoryAcademic Writing + 822021-06-14 14:43:36.4592182021-06-14 14:43:36.459218KeywordAcademic Writing + 832021-06-14 14:43:36.5212072021-06-14 14:43:36.521207AlignmentAcademic Writing2021-06-14 14:43:36.521207 + 842021-06-14 14:43:36.7020852021-06-14 14:43:36.702085KeywordAPA/MLA Style Guides + 852021-06-14 14:43:36.7491052021-06-14 14:43:36.749105StandardCEC_5.3 + 862021-06-14 14:43:36.8011002021-06-14 14:43:36.801100StandardUETS_7 + 872021-06-14 14:43:38.6728992021-06-14 14:43:38.672899CategoryAcceptance + 882021-06-14 14:43:38.7178922021-06-14 14:43:38.717892KeywordAcceptance + 892021-06-14 14:43:39.4689442021-06-14 14:43:39.468944CategoryAcceptance Testing + 902021-06-14 14:43:39.5319472021-06-14 14:43:39.531947KeywordAcceptance Testing + 912021-06-14 14:43:39.5769442021-06-14 14:43:39.576944KeywordMicrosoft Excel + 922021-06-14 14:43:39.6329422021-06-14 14:43:39.632942AlignmentAcceptance Testing2021-06-14 14:43:39.632942 + 932021-06-14 14:43:40.0671612021-06-14 14:43:40.067161KeywordCalipers + 942021-06-14 14:43:40.1141922021-06-14 14:43:40.114192KeywordCoordinate measuring machines (CMM) + 952021-06-14 14:43:40.1611602021-06-14 14:43:40.161160Keywordmicrometers + 962021-06-14 14:43:40.2011582021-06-14 14:43:40.201158Keywordrulers + 972021-06-14 14:43:40.2451952021-06-14 14:43:40.245195Keywordgauges + 982021-06-14 14:43:40.2911592021-06-14 14:43:40.291159KeywordStatistical process control (SPC) data collection devices + 992021-06-14 14:43:40.3471602021-06-14 14:43:40.347160KeywordDesign of experiments (DOE) software + 1002021-06-14 14:43:40.3951632021-06-14 14:43:40.395163KeywordMinitab + 1012021-06-14 14:43:40.4371612021-06-14 14:43:40.437161KeywordMATLAB + 1022021-06-14 14:43:40.4761902021-06-14 14:43:40.476190KeywordTolerance analysis software + 1032021-06-14 14:43:40.5251642021-06-14 14:43:40.525164KeywordAutoCAD + 1042021-06-14 14:43:42.2740182021-06-14 14:43:42.274018KeywordIBM Rational RequisitePro + 1052021-06-14 14:43:42.3287562021-06-14 14:43:42.328756KeywordUnified modeling language UML + 1062021-06-14 14:43:43.7697082021-06-14 14:43:43.769708KeywordData Variation + 1072021-06-14 14:43:44.9552352021-06-14 14:43:44.955235CertificationComp_TIA_Project_+ + 1082021-06-14 14:43:45.5728482021-06-14 14:43:45.572848KeywordScripting + 1092021-06-14 14:43:45.9143842021-06-14 14:43:45.914384KeywordWorkshop + 1102021-06-14 14:43:46.2073832021-06-14 14:43:46.207383KeywordUser Experience + 1112021-06-14 14:43:46.2783862021-06-14 14:43:46.278386CertificationAxelos_ITIL_1_Foundation + 1122021-06-14 14:43:46.7413862021-06-14 14:43:46.741386KeywordData Architecture + 1132021-06-14 14:43:47.3213882021-06-14 14:43:47.321388CategoryAccess Controls + 1142021-06-14 14:43:47.4023872021-06-14 14:43:47.402387KeywordAccess Controls + 1152021-06-14 14:43:47.4853862021-06-14 14:43:47.485386AlignmentAccess Controls2021-06-14 14:43:47.485386 + 1162021-06-14 14:43:47.7709582021-06-14 14:43:47.770958KeywordNetSupport School + 1172021-06-14 14:43:47.8219302021-06-14 14:43:47.821930KeywordLockDown Browser + 1182021-06-14 14:43:49.8600422021-06-14 14:43:49.860042CategoryAccess Network + 1192021-06-14 14:43:49.9020372021-06-14 14:43:49.902037KeywordAccess Network + 1202021-06-14 14:43:49.9510392021-06-14 14:43:49.951039KeywordMonitor + 1212021-06-14 14:43:50.0040702021-06-14 14:43:50.004070KeywordPerformance + 1222021-06-14 14:43:50.1880392021-06-14 14:43:50.188039AlignmentAccess Network2021-06-14 14:43:50.188039 + 1232021-06-14 14:43:50.3900392021-06-14 14:43:50.390039KeywordRouters + 1242021-06-14 14:43:50.4330412021-06-14 14:43:50.433041Certification350-201_CBRCOR + 1252021-06-14 14:43:50.6660422021-06-14 14:43:50.666042Certification300-410_ENARSI + 1262021-06-14 14:43:50.8690412021-06-14 14:43:50.869041Certification350-401_ENCOR + 1272021-06-14 14:43:51.0954302021-06-14 14:43:51.095430KeywordDesign + 1282021-06-14 14:43:51.1434102021-06-14 14:43:51.143410Certification300-420_ENSLD + 1292021-06-14 14:43:51.3194592021-06-14 14:43:51.319459CategoryAccount Analysis + 1302021-06-14 14:43:51.3804542021-06-14 14:43:51.380454KeywordAccount Analysis + 1312021-06-14 14:43:51.4204842021-06-14 14:43:51.420484KeywordAccount Reconciliation + 1322021-06-14 14:43:51.4594832021-06-14 14:43:51.459483CertificationCPA + 1332021-06-14 14:43:51.5064552021-06-14 14:43:51.506455CertificationCMA + 1342021-06-14 14:43:51.5524832021-06-14 14:43:51.552483CertificationCIA + 1352021-06-14 14:43:51.5934842021-06-14 14:43:51.593484CertificationCFE + 1362021-06-14 14:43:51.7144722021-06-14 14:43:51.714472AlignmentAccount Analysis2021-06-14 14:43:51.714472 + 1372021-06-14 14:43:51.9174552021-06-14 14:43:51.917455KeywordMicrosoft office Suite + 1382021-06-14 14:43:51.9624502021-06-14 14:43:51.962450KeywordSAS + 1392021-06-14 14:43:52.0044562021-06-14 14:43:52.004456KeywordBloomberg + 1402021-06-14 14:43:52.0524502021-06-14 14:43:52.052450KeywordTableau + 1412021-06-14 14:43:52.0974512021-06-14 14:43:52.097451KeywordReuters + 1422021-06-14 14:43:52.1505032021-06-14 14:43:52.150503KeywordQuickbooks + 1432021-06-14 14:43:52.1915022021-06-14 14:43:52.191502KeywordSage + 1442021-06-14 14:43:52.5843032021-06-14 14:43:52.584303KeywordGoogle Sheets + 1452021-06-14 14:43:52.6312812021-06-14 14:43:52.631281KeywordNetSuite + 1462021-06-14 14:43:52.6782842021-06-14 14:43:52.678284KeywordDynamics 365 Finance + 1472021-06-14 14:43:52.7222852021-06-14 14:43:52.722285KeywordOracle + 1482021-06-14 14:43:52.7702842021-06-14 14:43:52.770284KeywordSAP + 1492021-06-14 14:43:54.7174182021-06-14 14:43:54.717418CategoryAccount Management + 1502021-06-14 14:43:54.7614212021-06-14 14:43:54.761421KeywordAccount Management + 1512021-06-14 14:43:54.8044222021-06-14 14:43:54.804422KeywordBusiness Account Management + 1522021-06-14 14:43:54.8574232021-06-14 14:43:54.857423AlignmentAccount Management2021-06-14 14:43:54.857423 + 1532021-06-14 14:43:55.1534532021-06-14 14:43:55.153453KeywordHuman Resources Information Systems (HRIS) + 1542021-06-14 14:43:55.2134232021-06-14 14:43:55.213423KeywordHuman Capital Management (HCM) systems + 1552021-06-14 14:43:57.4281652021-06-14 14:43:57.428165CategoryAccountability + 1562021-06-14 14:43:57.4701582021-06-14 14:43:57.470158KeywordAccountability + 1572021-06-14 14:43:57.5521622021-06-14 14:43:57.552162AlignmentAccountability2021-06-14 14:43:57.552162 + 1582021-06-14 14:43:57.7561662021-06-14 14:43:57.756166KeywordMS Office + 1592021-06-14 14:44:00.2931652021-06-14 14:44:00.293165StandardAmerican_Nurses_Association_Nursing_Scope_and_Standards + 1602021-06-14 14:44:01.2087332021-06-14 14:44:01.208733CertificationAAMA-CMA + 1612021-06-14 14:44:01.5207292021-06-14 14:44:01.520729CategoryAccounting + 1622021-06-14 14:44:01.5587312021-06-14 14:44:01.558731KeywordAccounting + 1632021-06-14 14:44:01.6047302021-06-14 14:44:01.604730KeywordMonth-End Close Processes + 1642021-06-14 14:44:01.7867522021-06-14 14:44:01.786752AlignmentAccounting2021-06-14 14:44:01.786752 + 1652021-06-14 14:44:02.4704422021-06-14 14:44:02.470442KeywordCrystal reports + 1662021-06-14 14:44:02.5344422021-06-14 14:44:02.534442KeywordIBM Cognos + 1672021-06-14 14:44:11.9239752021-06-14 14:44:11.923975KeywordPareto analysis + 1682021-06-14 14:44:11.9643682021-06-14 14:44:11.964368CertificationCertified_Coding_Specialist + 1692021-06-14 14:44:12.0143332021-06-14 14:44:12.014333CertificationCertified_Professional_Coder + 1702021-06-14 14:44:12.0643372021-06-14 14:44:12.064337CertificationRegistered_Health_Information_Administrator + 1712021-06-14 14:44:12.1153382021-06-14 14:44:12.115338CertificationRegistered_Health_Information_Technician + 1722021-06-14 14:44:12.4026452021-06-14 14:44:12.402645CategoryAccounting Management + 1732021-06-14 14:44:12.4476762021-06-14 14:44:12.447676KeywordAccounting Management + 1742021-06-14 14:44:12.5326482021-06-14 14:44:12.532648AlignmentAccounting Management2021-06-14 14:44:12.532648 + 1752021-06-14 14:44:12.7453692021-06-14 14:44:12.745369KeywordQuicken + 1762021-06-14 14:44:12.7944052021-06-14 14:44:12.794405KeywordSalesforce + 1772021-06-14 14:44:12.8393682021-06-14 14:44:12.839368KeywordOracle Applications + 1782021-06-14 14:44:12.8803992021-06-14 14:44:12.880399KeywordMicrosoft Dynamics + 1792021-06-14 14:44:14.5289652021-06-14 14:44:14.528965CategoryAccounting Softwares + 1802021-06-14 14:44:14.5910122021-06-14 14:44:14.591012KeywordAccounting Softwares + 1812021-06-14 14:44:14.6359822021-06-14 14:44:14.635982KeywordExcel + 1822021-06-14 14:44:14.6799782021-06-14 14:44:14.679978KeywordAccounting Software + 1832021-06-14 14:44:14.7549862021-06-14 14:44:14.754986AlignmentAccounting Softwares2021-06-14 14:44:14.754986 + 1842021-06-14 14:44:14.9859802021-06-14 14:44:14.985980KeywordMicrosoft Dynamics GP + 1852021-06-14 14:44:15.2361662021-06-14 14:44:15.236166KeywordMicrosoft Dynamics Great Plains + 1862021-06-14 14:44:15.4658142021-06-14 14:44:15.465814KeywordApple + 1872021-06-14 14:44:15.5218212021-06-14 14:44:15.521821KeywordMicrosoft + 1882021-06-14 14:44:16.3152912021-06-14 14:44:16.315291KeywordOracle E-Business Suite + 1892021-06-14 14:44:16.3652922021-06-14 14:44:16.365292KeywordOracle Grid Computing + 1902021-06-14 14:44:16.4202912021-06-14 14:44:16.420291KeywordOracle Real Application Clusters + 1912021-06-14 14:44:20.2557592021-06-14 14:44:20.255759CategoryAccounting Systems + 1922021-06-14 14:44:20.3037592021-06-14 14:44:20.303759KeywordAccounting Systems + 1932021-06-14 14:44:20.3627572021-06-14 14:44:20.362757KeywordADP + 1942021-06-14 14:44:20.4257552021-06-14 14:44:20.425755KeywordWorkday + 1952021-06-14 14:44:20.4897582021-06-14 14:44:20.489758KeywordERP + 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 + + + 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_Frameworkworkspace50,64,53,63,55,61,5778user@email.com + 29124e022-0723-4bf3-8bec-0a271616b5eaSELpublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 + 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_Skillspublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 + 49903442f-ed1e-42d4-8d95-858a26204d500published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 + 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_Skillspublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 + 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_Collectionpublished2021-10-01 09:00:00.00000078,77,7538 + 72938a728-f6e2-41a1-8a3b-9a838a56d212Characterpublished2021-10-01 09:00:00.00000078,77,76,7548 + + + 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 + 46a02ac8d-2e00-4fac-8fde-1f8237bdd769Large-Scale Web Application BuildBuild large-scale web applications using the .NET Framework with minimum coding.18Published2021-10-01 09:00:00.0000002,2,7,7,9,955,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 + 55cef80ee-5799-4f5c-89e5-8e4908419a50Service-Oriented Application BuildBuild service-oriented applications using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,7,7,10,1055,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 + 670b1fe1b-ecf1-4ca8-88ee-311d4d93ca67Application Domain CreationCreate application domains and assemblies using attributes, formatting and parsing base types, collections, events and exceptions, files and data streams, and generics.18Published2021-10-01 09:00:00.0000002,2,3,3,7,755,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 + 70a79c4b2-a715-4596-8211-b57e7e9e791aWindows-Based Application CreationCreate Windows-based applications using the .NET framework.18Published2021-10-01 09:00:00.0000002,2,7,7,11,1155,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 + 8c396acc6-9f88-484f-935d-8dbf9488c428Geometric Primitive Shape CombinationCombine geometric primitive shapes into digital 3D representations of a component of an object.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 + 9d59223d2-7a38-4146-8f4e-f226262bc2afGraphical Representation CreationCreate a 3D graphical representation of a physical object using specialized software.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 + 10ca32343a-1df3-4cb3-aa90-5dd6290ab248Layered Component IdentificationIdentify the layered components of a physical object that make up the complete digital three-dimensional (3D) rendering.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 + 117c9aff0f-0f53-4f92-b867-afe080da54a9System DesignDesign systems that facilitate trust and improved performance.208Published2021-10-01 09:00:00.00000021,21,22,2236,464,559,627,1521,36,464,559,627,1521 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 13a99e1dfe-afb6-4a6b-9dc0-ca2b94e653f2Students with Exceptionalities Instructional Material CreationCreate accessible instructional materials for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 + 14d6045810-24a8-43ab-b438-8d070952470bMode of Instruction CreationCreate alternate modes of instruction to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 15c1adeadc-96da-4003-84f4-fd2a96c9a399Students with Exceptionalities Mode of Instruction CreationCreate alternate modes of instruction to meet the needs of students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 + 16e8debbf4-e0c2-4558-bc03-1d9281af8fcfLearning Style Lesson CreationCreate lessons that meet different learning styles for students.238Published2021-10-01 09:00:00.00000024,25,37133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 17b5eb4473-12a9-41bf-bcc4-583ac3715602Instructional Material ReviewEnsure instructional materials are accessible.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,37,40,41,42,43,44143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 183235ee81-e69c-457f-b541-0b536d0312d6Language Aquisition MethodsIdentify appropriate teaching methods to address adult language acquisition.238Published2021-10-01 09:00:00.00000024,25,37137,482,565,584,585,586,637,655,1797 + 19f2dfedae-7828-4fb2-befb-1461d131e9cfAdult Learning StrategiesIdentify learning strategies that support adult learner needs.238Published2021-10-01 09:00:00.00000024,25,37137,482,565,835,1797 + 208eb6bd37-2198-42b2-a740-81b984249eddIEP ImplementationImplement accommodations documented in students' individualized education programs (IEPs).238Published2021-10-01 09:00:00.00000024,25,37133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 21ba45f2e0-7a07-423d-874a-cf44dd4a51d4Students with Exceptionalities ImplementationImplement accommodations for each student with exceptionalities so that they learn effectively based on their unique characteristics and circumstances.238Published2021-10-01 09:00:00.00000024,25,37136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 22312e3598-5d79-46e9-83b2-5a2cbdbc00dbStudents with Exceptionalities Instruction and Assessment ImplementationImplement accommodations with fidelity for classroom instruction.238Published2021-10-01 09:00:00.00000024,25,37136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 23c37c5681-70e0-4aa4-b2ad-4a8c47637be0Subtitle IncorporationIncorporate subtitles into videos used in curriculum.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,31,34,37,38,39,44143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 24a0e75e3c-2c46-423f-ba96-7bab1e16ab55Visual and Graphic 508 IncorporationIncorporate visual and graphic design principles based on Section 508 principles.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,31,34,36,37,38,39,44143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 25985ab415-30d7-42da-89e5-cf826f437e69Instrucitonal Resource IntegrationIntegrate instructional resources to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,38,39,44,45143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 262db0d5a7-ab53-4c2b-ab82-c7feee468a74Instructional Strategy IntegrationIntegrate instructional strategies to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,38,39,44,45143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 27bd4fe8db-e173-4f2e-815c-54bd4f140acdStudents with Exceptionalities Instructional Strategy IntegrationIntegrate appropriate instructional strategies for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 + 28f69f0099-effe-41dd-b244-6c56b0d4a95fInstructional Technology IntegrationIntegrate instructional technologies to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,38,39,44,45143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 29365444df-bdbf-4bf4-9652-f4edeeaca72bAssessment and Testing ModificationModify assessments and testing conditions for learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,45,46143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 305655b01e-7d5b-490b-9946-cba49cef0023Students with Exceptionalities Assessment and Testing ModificationModify assessments and testing conditions for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 + 319df4810f-fe98-4cae-9892-a2396643daeaModify Assessment Conditions for Students with Language Learning NeedsModify assessments and testing conditions for students with language learning needs.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 + 32163af045-7f99-474e-a620-edee458ff8f8Integrate Technology for Students with ExceptionalitiesIntegrate appropriate technologies for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 + 336cbf4db6-17e8-44f5-8235-52de59774aa0Integrate Resources for Students with ExceptionalitiesIntegrate appropriate resources for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 + 340b50baf3-2153-4757-b160-c5d94aa54070Implement Assessment AccommodationsImplement accommodations with fidelity for assessments.238Published2021-10-01 09:00:00.00000024,25,37136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 35d752a9ca-55d1-4220-8e74-d1743120e9c0Student With Exceptionalities AdvisingAdvise students with exceptionalities on academic issues that they may face.478Published2021-10-01 09:00:00.00000048,49,50136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 368cd1e0c0-c4ec-48a8-873a-b5a1f5d983fdGoal EstablishmentAssist students with identifying and establishing academic and professional goals.478Published2021-10-01 09:00:00.00000048,49,50122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 3784f9a1f8-c1e8-4ee3-b602-09194e2db361Student Development and Achievement PlanCreate a plan collaboratively to support student development and achievement.478Published2021-10-01 09:00:00.00000030,31,32,33,35,36,48,49,50,51,52123,125,126,129,134,135,136,143,146,148,480,481,483,484,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,843,846,851,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,1808,1813,2467,2468,2469,2470,2471,2472 + 38b82bfaea-eb56-40ed-99f2-6911e7b65901Adult Learner OpportunitiesExplore continued-learning opportunities for adult learners.478Published2021-10-01 09:00:00.00000048,49,50137,482,565,835,1797 + 39acf9865e-26ae-43e9-80f5-739ae186dcbbAdult Learner Support SystemsIdentify adult learners' educational needs with support systems based on work experience.478Published2021-10-01 09:00:00.00000048,49,50137,482,565,835,1797 + 40ec088d7f-031b-4bb4-ad29-5269ff1b23b9Academic Need IdentificationIdentify the academic needs of students in order to improve their knowledge or skills.478Published2021-10-01 09:00:00.00000048,49,50133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 41d3d54a52-9042-4f28-8cfc-88873c6e5da7Student and Family MentoringMentor students and families to achieve academic goals.478Published2021-10-01 09:00:00.00000030,31,32,33,36,48,49,50143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 426788a51d-6919-4ffa-b15c-e8219463f3a1Future PreparationPrepare students and families for the future by encouraging them to address learning needs.478Published2021-10-01 09:00:00.00000048,49,50133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 437814a1fb-a886-4076-94e8-5f1bda98e65aSelf Resource PromotionPromote oneself as a resource for students and their families.478Published2021-10-01 09:00:00.00000030,31,32,33,36,48,49,50,53,54,55,56123,125,126,129,134,135,136,143,146,148,480,481,483,484,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,843,846,851,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,1808,1813,2467,2468,2469,2470,2471,2472 + 446ec2f763-64c3-463d-8a3a-911c86394e02Conern ReponseRespond to student or family concerns.478Published2021-10-01 09:00:00.00000030,31,32,33,36,48,49,50123,125,126,129,134,135,136,143,146,148,480,481,483,484,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,843,846,851,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,1808,1813,2467,2468,2469,2470,2471,2472 + 4521e0feef-6fc5-4861-95bb-ec4afd32bd9aSchool Resource ServiceServe as a resource in the school for students with exceptionalities and their families.478Published2021-10-01 09:00:00.00000048,49,50136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 467fbfa2ee-0474-4245-ad64-9f9069b2adc9Timeline and Planning RecommendationSuggest timelines and plans for academic work and study.478Published2021-10-01 09:00:00.00000048,49,50122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 47d986f648-5717-4283-a277-38e1a0af7ab7Student SupportSupport students in making appropriate choices relevant to their academic goals.478Published2021-10-01 09:00:00.00000048,49,50122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 48bf06dec1-cd48-40da-89df-07def4fa5592Self-Belief CultivationCultivate a belief in self, self-regulation, and perseverance to achieve educational goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 49c90ad0d1-e789-4acd-b106-850b4a573c3cLong-Term PerserveranceDemonstrate perseverance to attain long-term academic goals despite academic challenges.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,58,59,60,61,62,63,64,65,66136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 50ba7832fd-0e7f-45f1-817e-13488f583d5dWillingness and PerseveranceDemonstrate the willingness and perseverance to achieve long-term academic goals despite short-term setbacks.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,58,59,60,61,62,63,64,65,66,67,74,752,1,4,3 + 510d25a25f-413b-47a7-9b03-cdc52b69d6f3Long-Term Goal DevelopmentDevelop long-term goals despite short-term concerns.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,41,58,59,60,61,62,63,64,67,68174,489,567,913,1883,1884,1885,1886,1887 + 525f45bdcc-eeab-4cac-9b51-89bb0b605b26Student EncouragementEncourage students to remain committed to academic and professional goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,67,76,77122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 5316faefb8-dc18-45d6-bd8d-2265d5228eacMistake EvaluationEvaluate mistakes to reach long-term academic goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,67,68,74,781,2,3,4 + 54bdc11475-a2c9-4d7b-9dfc-ca2119a89fc5Adult Learner Persistence DevelopmentRecommend a means to overcome learning barriers for adult learners.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,35,36,41,42,58,59,60,61,62,63,64,65,66,68137,482,565,835,1797 + 553ecb3897-e1e3-4ec0-bb42-b3bdb7c0d0e0Thinking PatternsIdentify thinking patterns that interfere with persevering through short-term concerns or setbacks.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,41,42,58,59,60,61,62,64,65,66,67,74,78,791,2,3,4 + 5664dcd376-abdd-4167-a96d-3ae85659464cNursing PerseverencePersevere through challenges and setbacks toward nursing academic goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,64,65,66,67174,489,567,913,1883,1884,1885,1886,1887 + 57bf62682c-2ab5-4004-ae57-9d4725c412e6PersistencePersist along incremental steps toward achieving an academic goal.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,64,65,66,67,74,751,4,3,2 + 58c64c1844-874e-42ce-8537-5f2bfb539ea8PerserverancePromote perseverance as a positive quality.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,64,65,66,67122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 5976c5f61a-682e-421e-9c2d-5a504bdad20eGoal ReinforcementReinforce the importance of reaching academic and professional goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,42,58,59,60,61,62,65,66,67122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 60fb3dfbbb-aec8-4009-a6fe-8edc8c6e7c63Short-Term to Long-Term Education GoalsTransition short-term concerns to long-term or higher-order educational goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,67133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 610e8343c1-d9bc-4e1f-a7a7-5408818c8e77StrategiesImplement strategies to take the current situation into perspective and weigh reaction to current circumstances against positive consequences of achieving longer-term academic goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,74,781,2,3,4 + 62bad37fb3-a9a9-49f7-8bab-387184ba2a2bChallenge PerserveranceWithstand challenges and setbacks to persevere toward one's educational goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,40,41,58,59,60,61,62,65,66,67133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 634bddfe6b-fb94-47f7-bdea-5fd9b8321ff4Identify Thinking PatternsIdentify thinking patterns that interfere with perseverance.578Published2021-10-01 09:00:00.00000058,59,60,61,62,74,78,803,2,1 + 64816440ce-8a67-4980-9b8b-355dd21e2a3fEvaluate Mistakes to LearnEvaluate mistakes to further learning.578Published2021-10-01 09:00:00.00000058,59,60,61,62,74,78,801,2,3 + 656fe88d16-b003-4880-a644-36730fa74171Develop Adult Learner PersistenceDevelop adult learners' persistence through learning or life obstacles.578Published2021-10-01 09:00:00.00000058,59,60,61,62137,482,565,835,1797 + 66ffb662ca-2bd6-4d0c-a2ec-c0dceaaf9da7Develop Long-Term GoalsDevelop long-term goals despite short-term concerns.578Published2021-10-01 09:00:00.00000058,59,60,61,62174,489,567,913,1883,1884,1885,1886,18875 + 67fb8c9d06-faa8-42f1-b4e2-3ac468e69b15Professional LanguageConvey academic information using professional language.818Published2021-10-01 09:00:00.00000082,83174,489,567,913,1883,1884,1885,1886,1887 + 681f962e2f-3a2a-4310-be51-2cfb286ed7d0Teaching Structure, Style, and FormattingGuide students in using appropriate structures, style, and formatting for academic writing.818Published2021-10-01 09:00:00.00000082,83,84,85,86122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 69402a2737-e929-4de6-b82d-c584ad89fde8Adult Learner InstructionInstruct adult learners how to write using academic writing styles.818Published2021-10-01 09:00:00.00000082,83,85,86137,482,565,835,1797 + 7097b712d6-1715-4369-a7d2-60b880cff123Valid Data Source IdentificationInstruct students on how to effectively identify appropriate and valid data sources.818Published2021-10-01 09:00:00.00000082,83,84122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 712033cce3-eb7c-4c47-9276-424480c6b5eaArgument Presentation InstructionInstruct students on how to present arguments logically and factually.818Published2021-10-01 09:00:00.00000082,83,84122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 7256f73c31-fa90-4052-9fea-ed6aa4a3fdbePosition SupportApply a formal writing style, employing evidence to support one's position.818Published2021-10-01 09:00:00.00000082,83,85,86133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 + 736ae74dcc-d3f6-4b70-88ab-64db76e07e1aScholarly ConversationApply effective writing skills to convey ideas, make arguments, and engage in scholarly conversation.818Published2021-10-01 09:00:00.00000082,83,85,86136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 7448a7c96c-187f-45ab-b0f9-441319ed332bEvidence-Based ReasoningWrite using evidence-based reasoning.818Published2021-10-01 09:00:00.00000082,8354,174,489,567,913,1883,1884,1885,1886,1887 + 75e49fdbb4-2d3e-4fee-953a-dd46d7e34fd1Recognize Views of OthersRecognize that others will think differently and will hold different views, interests, and beliefs.878Published2021-10-01 09:00:00.000000886,7 + 76b07500ff-abb9-4616-aa3d-52114b0ac182Exchange IdeasExchange ideas freely.878Published2021-10-01 09:00:00.000000887 + 77952777f9-e5f9-4ade-9a03-c70366c49fe5Free from PrejudiceBe free of prejudice and discrimination.878Published2021-10-01 09:00:00.000000886,7 + 7830045c0e-91e5-4afb-8c61-d81952a821edAppreciate DiversityAppreciate the richness of diversity, diverse ideas, and diverse communities.878Published2021-10-01 09:00:00.000000886,7 + 79adc069c3-881d-4c5d-a2e0-3f021adffc88Gap AnalysisConduct a gap analysis between actual deliverables and acceptance testing requirements.898Published2021-10-01 09:00:00.00000090,91,9238,43,464,559,632,637 + 809ce973e6-4402-44e7-88cc-63cfe8b71751Status Report CreationCreate a status report for contract deliverables.898Published2021-10-01 09:00:00.00000090,91,9238,43,464,559,632,637 + 812617d28b-2c18-42ff-9ab1-6f020770f00eDesignDesign test plans, scenarios, scripts, or procedures for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,656,665,668 + 825e6f6f95-20fc-43aa-996a-199427ba7473Specifications and ProceduresDetermine acceptance testing specifications and procedures from existing documentation.898Published2021-10-01 09:00:00.00000090,92,93,94,95,96,97,98,99,100,101,102,10383,85,469,470,561,696,701,702,703,704,705,706,707,708,709,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484 + 83cdf754f4-e161-44ba-b68d-0a8c1a62eaebStandard DevelopmentDevelop standards, methods, and procedures to evaluate product quality or release readiness for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,665,668,2485 + 8406cdf44d-0ce3-477b-9e1a-eeacba6ab10fStandard DocumentationDocument standards, methods, and procedures to evaluate product quality or release readiness for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,665,668,2485 + 85812dcb2f-1aa4-4039-8177-b83655e45594Test DocumentationDocument test procedures to ensure replicability and compliance with standards for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,665,668,2486 + 8656ff1f06-e1e3-4dc8-b3f0-8dfc7bd385b6Requirement GenerationGenerate a list of acceptance testing requirements.898Published2021-10-01 09:00:00.00000090,91,92,104,10538,43,464,559,632,637 + 87fbab883f-d79f-47c2-b496-1ed749bc39beProduct Dimension MeasurementMeasure dimensions of products to verify conformance acceptance testing specifications.898Published2021-10-01 09:00:00.00000090,92,93,94,95,96,97,98,99,100,101,102,10383,85,469,470,561,696,701,702,703,704,705,706,707,708,709,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484 + 8842703f26-b67f-4001-8ea8-18ea3f01e8a3Inspection RecordRecord inspection or test data and acceptance testing status.898Published2021-10-01 09:00:00.00000090,92,93,94,95,96,97,98,99,100,101,102,10383,85,469,470,561,696,701,702,703,704,705,706,707,708,709,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484 + 89545377ac-3618-4c65-afef-0c255351ad89Acceptance Test Data Variations DefinitionDefine variations in data that are possible for an acceptance testing script.898Published2021-10-01 09:00:00.00000090,92,10654,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 + 90bb6a57c6-0779-46c7-b64a-0f6bb7827e70Determine Acceptance Testing DiscrepanciesDetermine if there are discrepancies between original software specifications and final acceptance testing scenarios.898Published2021-10-01 09:00:00.00000090,90,92,92,107,10754,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493,54,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 + 9115bec8cc-83ec-4722-a1fd-cf67eb4c9c1dResolve User Concerns During Acceptance TestingResolve end users' concerns during acceptance testing processes.898Published2021-10-01 09:00:00.00000090,9254,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 + 92438be742-fe7c-48f0-82d1-e70a1b882d25Acceptance Testing Script Failure DocumentationDocument acceptance testing script failures.898Published2021-10-01 09:00:00.00000090,92,10854,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 + 93c44f0a53-f9f4-46e9-beb3-66b6495c4ee5User Acceptance Testing (UAT) Workshops ManagementManage user acceptance testing (UAT) workshops.898Published2021-10-01 09:00:00.00000090,92,10954,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 + 9473ec441f-7c07-42d2-98c8-c8461e7f7c38User Experience Acceptance Test DesignDesign alterations to user experience components to meet acceptance testing criteria.898Published2021-10-01 09:00:00.00000090,90,92,92,110,110,111,11158,466,560,667,2494,58,466,560,667,2494 + 9570a30c21-b47e-49d1-87ed-5c51497259b5Data Architecture Acceptance Test DesignDesign alterations to data architecture components to meet acceptance testing criteria.898Published2021-10-01 09:00:00.00000090,92,11257,466,560,661,2494 + 96f529adfd-0cfa-480a-a39b-847636c62639Medical Record AccessAccess relevant medical records needed to protect health information.1138Published2021-10-01 09:00:00.000000114,115114,476,563,771,772,773,1732,1733,1734 + 977e167ecb-6808-4749-93a5-8297d7c9882aProgram and Resource DeterminationDetermine appropriate computing programs and online resources.1138Published2021-10-01 09:00:00.000000114,115,116,11754,122,123,125,126,127,128,129,131,198,466,480,495,560,565,569,655,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778,2488 + 98b7519fda-0e4d-4ff2-9307-f03a3a83bb08Policy EnforcementEnforce policies regarding online resources.1138Published2021-10-01 09:00:00.000000114,11554,122,123,125,126,127,128,129,131,198,466,480,495,560,565,569,655,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778,2488 + 992d61fdd0-2ae6-4e62-9bcc-1a1b635ed532HIPAA ImplementationImplement Health Insurance Portability and Accountability Act (HIPAA)-compliant concept of minimum and necessary user access for the role of the worker.1138Published2021-10-01 09:00:00.000000114,115114,476,563,769,771,772,773,1730,1732,1733,1734 + 10049bf2af4-d834-4af9-bbcd-64c1fe59fc0aStudent Resource CommunicationInform students of online resources for guidelines and policies.1138Published2021-10-01 09:00:00.000000114,11554,122,123,125,126,127,128,129,131,466,480,560,565,569,655,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778,2488 + 1010e2014a3-2076-4f49-a60e-04b273952effResource MonitoringMonitor computing resource use and abuse.1138Published2021-10-01 09:00:00.000000114,115122,123,125,126,127,128,129,131,198,480,495,565,569,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 10210913e85-83f1-4556-8fff-4213f3b4cf57Network Router Performance MonitoringMonitor network routers for performance issues.1188Published2021-10-01 09:00:00.000000119,120,121,12256,57,466,560,657,659,662,2489,2490,2495,2496 + 10378d61a82-8302-488c-9c3f-bf01d88e5ff9Network Router Security MonitoringMonitor network routers for security issues.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,124,12456,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 104f5b83170-bff2-4bff-93eb-660a2a9f6653Network Routers Security ConfigurationConfigure security on network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,125,12556,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 105b749ad2f-465a-41a3-92be-ba7072ce09b2Router Network Traffic ConfigurationConfigure network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,119,122,122,122,125,125,125,126,126,12656,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 106a3fe184d-921a-45f6-a384-308ca77b4498Network Connection DesignDesign a network connection between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,127,127,128,12856,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 108aa3b83b9-1d08-4ada-8c3a-8034500da009Financial Data ComparisonCompare financial data against third-party statements to confirm balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,136,137,138,139,140,141,142,14349,52,465,559,644,645,646,647,651,652 + 109913ed1f1-cca5-47b7-bf7e-a3a3af63ad6cReconciliationConduct periodic reconciliations of financial account balances to ensure accuracy.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,136,137,138,139,140,141,142,14349,52,465,559,644,645,646,647,651,652 + 110ba97364c-4d8d-4da2-bf07-4279d5255535Financial AdjustmentsCreate financial adjustments to address account discrepancies.1298Published2021-10-01 09:00:00.00000091,130,131,132,136,142,144,145,146,147,1487,9,462,558,589,590,592,1461,1462,2498,2499 + 111543dfbaf-d753-4add-b061-0b838dce7c6dCash Guideline and Policy CreationCreate guidelines and policies around cash processes that are adequate and effective to prevent significant errors in calculating cash balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1123b557765-d719-4a71-9b16-e40eff12d81cInternal Process DesignDesign enterprise-wide internal processes to manage reconciliation of accounts, ensuring internal audit compliance.1298Published2021-10-01 09:00:00.000000130,131,132,134,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1135b351b80-3c20-4f69-b2a8-9b4c890f0fbbInternal Process ImplementationImplement enterprise-wide internal processes to manage reconciliation of accounts, ensuring internal audit compliance.1298Published2021-10-01 09:00:00.000000130,131,132,134,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 114ed718562-96cc-409c-a949-7e4702db5f30Account Invoice and Payment MatchingMatch account invoices with recorded payments in an accounting system.1298Published2021-10-01 09:00:00.00000091,130,131,132,134,135,136,142,144,145,146,147,1487,9,462,558,589,590,592,1461,1462,2498,2499 + 11526746e9b-67d3-4a0e-84a6-1f5aa74ff77fFinancial Data RecalculationRecalculate financial data to verify valuation of account balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,136,137,138,139,140,141,142,14349,52,465,559,644,645,646,647,651,652 + 116a7bd2eee-4d7e-4686-a241-209b3377a499Entry Error ResolutionResolve entry errors and reconciles ledgers to ensure cash amounts agree with bank balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1171e0f0efe-723b-4736-824e-fbb78c1157e9Aging ReportsRun aging reports to compare invoices against variable payment terms on an account.1298Published2021-10-01 09:00:00.00000091,130,131,132,134,135,136,142,144,145,146,147,1487,9,462,558,589,590,592,1461,1462,2498,2499 + 118ace9e8ac-802f-4388-b845-221b4343698fAnalyze Processes and Systems for ImprovementsAnalyze current processes and systems for efficiency and process improvements.1298Published2021-10-01 09:00:00.000000130,131,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 119be0c058e-58b9-4651-b396-5576cb3a0231User SimulationAct as a user within many domains, networks, and cloud subscriptions.1498Published2021-10-01 09:00:00.000000150,151,15254,466,560,655,2488 + 12040c30943-f9e4-4b15-819e-126c25cdde41Application InteractionInteract with applications, networks, and data in a predefined manner.1498Published2021-10-01 09:00:00.000000150,151,15254,466,560,655,2488 + 121ab2a77fa-ff91-4d7a-9822-3fe787171c86Policy DevelopmentDevelop policies detailing proper uses of system and user accounts for human resource�related systems.1498Published2021-10-01 09:00:00.000000150,151,152,153,15436,464,559,627,629 + 122b5ce2cb4-8628-45f6-b325-11c2e8ff42f5User Account EstablishmentEstablish system and user accounts for new employees.1498Published2021-10-01 09:00:00.000000150,151,152,153,15436,464,559,627,629 + 1232a0d0b6b-82c4-494b-8540-29c43745d3f8Employee Account MainteanceMaintain employee accounts and records, including updates to such information.1498Published2021-10-01 09:00:00.000000150,151,152,153,15436,52,464,465,559,627,629,651,652 + 124c3068e15-dae5-4b5f-ad92-5927737962dfDevice Configuration ManagementManage configuration of and access to applications on a device.1498Published2021-10-01 09:00:00.000000150,151,15254,466,560,655,2488 + 12521c640f7-e87c-47c2-b985-70e3dee34602Organizatonal Policy UseImplement organizational policies to identify the criteria by which customer accounts are designated and classified to rank them, accommodate the account, and mitigate concerns.1498Published2021-10-01 09:00:00.000000150,151,1521,2,4,5,7,10,12,17,27,30,35,38,43,54,223,227,228,460,461,462,463,464,466,503,506,558,559,560,571,572,581,582,584,585,586,589,593,595,600,614,618,626,632,637,655,1024,1036,1448,1450,1452,1453,1454,1457,1464,1471,1477,1494,1500,1520,1528,1533,2021,2033,2488,2500,2501 + 126a400b351-94d6-488a-b443-5f7f16a44322Strategic Plan ExaminationExamine the organization's strategic plan and long-term objectives to define the criteria for key account status and develop a procedure to establish benefits for accounts with key account management status.1498Published2021-10-01 09:00:00.000000150,151,1521,2,5,7,10,12,17,27,30,35,38,54,223,227,228,460,461,462,463,464,466,503,506,558,559,560,571,572,581,582,586,589,593,595,600,614,618,626,632,655,1024,1036,1448,1450,1454,1457,1464,1471,1477,1494,1500,1520,1528,2021,2033,2488,2500,2501 + 127424856e1-6fdb-4da0-a79a-8258f2e8d958Cross-Functional Team CollaborationCollaborate with a cross-functional team to evaluate which accounts are the best fit for the range of products and services the company offers, and which pose the biggest risk in impacting the company's bottom line.1498Published2021-10-01 09:00:00.000000150,151,1521,2,4,5,7,10,12,17,27,30,35,38,43,223,227,228,460,461,462,463,464,503,506,558,559,571,572,581,582,584,585,586,589,593,595,600,614,618,626,632,637,1024,1036,1448,1450,1452,1453,1454,1457,1464,1471,1477,1494,1500,1520,1528,1533,2021,2033,2500,2501 + 1284ec33d34-566e-4db2-b4a7-63aa4480ee26Plan DevelopmentDevelop a key account management plan that includes a vision, mission, and strategic objectives aligned to customer marketing and sales strategy.1498Published2021-10-01 09:00:00.000000150,151,1521,2,4,5,7,10,12,17,27,30,35,38,43,223,227,228,460,461,462,463,464,503,506,558,559,571,572,581,582,584,585,586,589,593,595,600,614,618,626,632,637,1024,1036,1448,1450,1452,1453,1454,1457,1464,1471,1477,1494,1500,1520,1528,1533,2021,2033,2500,2501 + 129ffd8019a-8f1f-4f2f-b8a4-a5603347f3cdMedical Error CommunicationCommunicate medical errors promptly with transparency and honesty to the attending provider and organization.1558Published2021-10-01 09:00:00.000000156,157174,489,567,913,1883,1884,1885,1886,1887 + 130c03a07ed-97cd-4c71-aa0f-5a8111d432a6Employee Action CorrectionCorrect employees actions when their results do not meet expectations.1558Published2021-10-01 09:00:00.000000156,157,15875,76,83,85,469,470,561,687,688,689,696,701,702,703,704,705,706,707,708,709,1611,1612,1613,1614,1615,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2502,2503,2504 + 1319bb2a948-6664-4560-aed0-f160dc80a94aSchool Policy AdherenceDemonstrate responsibility for their job duties by adhering to school and district policies.1558Published2021-10-01 09:00:00.000000156,157136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 + 1325ba3dd8e-7e50-467f-aaea-9b81c61384f8Information DisclosureDisclose relevant information to students, colleagues, and administrators.1558Published2021-10-01 09:00:00.000000156,157137,482,565,835,1797 + 133a0afb45f-7f53-41b8-a64a-4988511bf1feRationale for ActionsExplain the rationale for actions taken toward students, colleagues, or administrators.1558Published2021-10-01 09:00:00.000000156,157137,482,565,835,1797 + 13464ba523a-c6d7-48d8-bff7-199189d859d3Rationale for DecisionsExplain the rationale for decisions made to students, colleagues, or administrators.1558Published2021-10-01 09:00:00.000000156,157137,482,565,835,1797 + 1359e6a56ad-267a-4bc1-9f79-1a78eaace39fIntegrity for DecisionsMaintain integrity for decisions, behavior, and actions of self, students, faculty, and staff of the organization.1558Published2021-10-01 09:00:00.000000156,157122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 + 136e069470c-d95b-4c37-ad3a-25d0fda3b81eEmployee Performance MeasurementMeasure employee performance against goals.1558Published2021-10-01 09:00:00.000000156,157,15875,76,83,85,469,470,561,687,688,689,696,701,702,703,704,705,706,707,708,709,1611,1612,1613,1614,1615,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2502,2503,2504 + 137c6433604-e4f2-4801-9a49-64903581fcb6Collective ResponsibilityTake collective responsibility for a total organization's successes and failures within the scope of influence.1558Published2021-10-01 09:00:00.00000030,31,32,33,36,40,41,43,67,68,156,157143,146,483,484,565,843,846,1806,1808,2467,2468,2469,2505 + 138f9828ece-14e7-4485-a01a-1036777ee6b6Personal Decision OwnershipTake ownership of personal decisions regardless of the outcome.1558Published2021-10-01 09:00:00.000000156,157,15875,76,83,85,469,470,561,687,688,689,696,701,702,703,704,705,706,707,708,709,1611,1612,1613,1614,1615,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2502,2503,2504 + 139db5bc08d-9bb6-45d6-95c6-0ff839135451Medical Practice Compliance EvaluationEvaluate current medical practices to ensure compliance with regulations.1558Published2021-10-01 09:00:00.000000156,157,159112,113,168,177,476,489,563,567,759,762,766,900,916,1720,1723,1727,1866,18905 + 14060766fb3-7933-4bff-b0fe-f7c4fcabcbc2Peer Performance Expectation CommunicationCommunicate performance expectations with peers.1558Published2021-10-01 09:00:00.000000156,157,159112,113,168,177,181,476,489,563,567,759,762,766,900,916,936,1720,1723,1727,1866,1890,25065 + 141a2fcf893-cf0e-4c58-9559-e7344aaddd7cTeam Expectation VerificationVerify team members meet expectations.1558Published2021-10-01 09:00:00.000000156,157,159112,113,168,177,181,476,489,563,567,759,762,766,900,916,936,1720,1723,1727,1866,1890,25065 + 142cfc99fa0-609c-4b6a-8364-9c84af0605a8Medication Medical Order VerificationVerify medical orders before dispensing medications.1558Published2021-10-01 09:00:00.000000156,157,159,160112,168,181,197,476,489,494,563,567,568,762,900,936,976,1723,1866,1966,25065 + 1434e15deeb-a0cb-4f36-9146-ddc8a8815262Economic Movement AnalysisAnalyze the economic movement within an organization, documenting and communicating trends and summaries.1618Published2021-10-01 09:00:00.000000132,133,134,135,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,204,462,463,464,465,467,473,474,497,558,559,560,562,569,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 14431a87113-9bee-444a-8314-f4d8a316b869Economic Status CommunicationCommunicate the economic status and trajectory of an organization to key stakeholders.1618Published2021-10-01 09:00:00.000000132,133,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,204,462,463,464,465,467,473,474,497,558,559,560,562,569,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 145d9b6893f-3373-4f6f-9c79-f7e4f7b9dd33Journal Entry CreationCreate a journal entry in an accounting system.1618Published2021-10-01 09:00:00.00000028,29,43,91,132,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 + 1467e2700dd-092a-42ff-bbcc-4de5225fb4e1General Ledger DefinitionDefine an organization's general ledger.1618Published2021-10-01 09:00:00.00000091,132,142,145,146,147,148,162,163,1649,32,38,43,45,47,48,50,52,62,63,97,108,204,462,464,465,467,473,474,497,558,559,560,562,569,592,620,621,622,632,637,639,642,643,648,651,671,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1587,1588,1685,1712,2497,2498,2507 + 147a4cd8fbd-ce21-4f4f-aa60-cbd28fc5da60Economic Cost DefinitionDefine the economic cost of a project for an organization.1618Published2021-10-01 09:00:00.000000132,133,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,462,463,464,465,467,473,474,558,559,560,562,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 148de76aa08-cad9-43d7-a675-f8b4e2c8c0b5Accounting Models DevelopmentDevelop accounting models for forecasting inventory needs, orders, and profitability.1618Published2021-10-01 09:00:00.000000132,133,162,163,1641,2,7,8,9,10,11,12,13,17,23,30,460,462,463,558,581,582,591,592,593,594,595,596,600,610,618,1448,1449,1450,1460,1461,1462,1464,1465,1466,1467,1468,1469,1470,1471,1473,1477,1488,1500,1501,1502,1503,1504,1505,1506,2498,2509,2510,2511,2512,2513,2514,2515 + 1498a33373d-0091-4dc3-ad5e-773fb3b6bca7Business Processes DevelopmentDevelop business processes for financial systems.1618Published2021-10-01 09:00:00.00000091,132,133,134,135,142,145,146,147,148,162,163,1649,32,38,43,45,47,48,50,52,62,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,671,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1587,1588,1685,1712,2497,2498,2507 + 1504b986f4c-b49e-46a8-a1d8-05e61e78697fClosing Procedures EstablishmentEstablish accounting closing procedures in compliance with generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.000000132,134,162,163,1641,2,9,10,11,12,13,23,30,204,460,462,463,497,558,569,581,582,592,593,594,595,596,610,618,1448,1449,1450,1461,1462,1464,1465,1466,1467,1468,1469,1470,1471,1473,1488,1500,1501,1502,1503,1504,1505,1506,2498,2509,2510,2511,2512,2513,2514,2515 + 151cf5de322-52e0-42ec-9f5f-1eb6b932bf32Full Cycle Financial AccountingExecute full cycle financial accounting, inclusive of accounts receivable, accounts payable, and payroll.1618Published2021-10-01 09:00:00.000000132,162,163,1641,2,5,7,9,10,12,17,27,30,35,36,38,43,45,47,48,50,52,63,97,108,223,227,228,460,461,462,463,464,465,467,473,474,503,506,558,559,560,562,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,627,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 + 152ffe4341a-f032-42ac-9e53-8e54ef2233ccBest Practices ImplementationImplement financial best practices of the specific business.1618Published2021-10-01 09:00:00.00000091,132,134,135,142,145,146,147,148,162,163,1649,32,38,43,45,47,48,50,52,62,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,671,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1587,1588,1685,1712,2497,2498,2507 + 1536ee5dd79-e607-4381-8446-41f3372b2436Closing Procedure ImplementationImplement month-end and year-end closing accounting procedures for an organization.1618Published2021-10-01 09:00:00.00000028,29,43,132,134,162,163,1641,2,9,10,11,12,13,14,15,23,27,30,204,460,462,463,497,558,569,581,582,592,593,594,595,596,597,598,610,614,618,1448,1449,1450,1461,1462,1464,1465,1466,1467,1468,1469,1470,1471,1473,1474,1475,1488,1494,1500,1501,1502,1503,1504,1505,1506,2498,2509,2510,2511,2512,2513,2514,2515 + 1548aefe35f-03e9-4b01-8a89-0e5e3f368d9fAccounting Operations LeadershipLead accounting operations and the preparation of financial reports to ensure the accurate and timely dissemination of financial statements and budget reports.1618Published2021-10-01 09:00:00.000000132,162,163,1641,2,5,7,9,10,12,17,27,30,32,35,36,38,43,45,47,48,50,52,63,97,108,223,227,228,460,461,462,463,464,465,467,473,474,503,506,558,559,560,562,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,627,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 + 15528be12cb-12e2-47ec-a8fd-546c97662509Account Reconciliation ProcessesPerform account reconciliation processes at year-end.1618Published2021-10-01 09:00:00.00000028,29,43,91,132,134,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 + 1569eaca429-0ac5-408f-8ad6-b27c56f2f973General Ledger PreparationPrepare a general ledger for an organization.1618Published2021-10-01 09:00:00.00000028,43,91,132,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 + 157da166158-28f2-4d78-a925-af3bd97dc22fFinancial Report PreparationPrepare financial reports in accordance with generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.00000028,29,43,91,132,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 + 158dbdcd291-f1ce-4eec-a64d-994c8ea73acbFinancial Statement PreperationPrepare financial statements in accordance with generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.00000029,43,91,132,134,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 + 1598c351161-045f-472a-9b10-11975643c8efReconciliation Schedules PreparationPrepare reconciliation schedules for balance sheet accounts, including accounts receivable and bad debt reserves.1618Published2021-10-01 09:00:00.000000132,134,162,163,1641,2,5,7,9,10,12,17,27,30,32,35,36,38,43,45,47,48,50,52,63,97,108,204,223,227,228,460,461,462,463,464,465,467,473,474,497,503,506,558,559,560,562,569,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,627,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 + 160fe0a9a50-0c52-40bf-8cd4-1b06bfdb396aEconomic Movement ProcessProcess the economic movement within an organization.1618Published2021-10-01 09:00:00.000000132,133,134,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,204,462,463,464,465,467,473,474,497,558,559,560,562,569,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 161b775653f-98ee-4e46-8eea-ec5ce6a5d5d3Day-to-Day RecordingRecord the day-to-day financial transactions to ensure complete, accurate, and timely financial statements while reconciling discrepancies.1618Published2021-10-01 09:00:00.000000132,162,163,1641,2,5,7,9,10,12,17,27,30,32,35,38,43,45,47,48,50,52,63,97,108,204,223,227,228,460,461,462,463,464,465,467,473,474,497,503,506,558,559,560,562,569,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 + 16226a02cf5-31c9-43f7-b017-043f0cab8b85Account Balances AdjustmentAdjust account balances from cash basis to accrual basis and presents month-end results according to generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,204,465,497,559,569,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1637bc2d16d-6e7c-44f8-859b-0aac2c320bafFinancial Reviews ConductionConduct financial reviews of month-end reports for accuracy to communicate discrepancies.1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,204,465,497,559,569,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 164a785ef66-12d2-49a7-b8a1-19bfe298e837Standard Procedures DevelopmentDevelop standard procedures and cross-training to streamline processes, increase accuracy, and decrease overall month-end closing duration.1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 165bab8efa3-3627-49db-b076-8bc74d469ac1Improvement RecommendationsRecommend improvements to senior management on internal control and audit of the month-end close process.1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 16618282ff8-f4b5-435b-b5ca-4dff4001448eMedical Claim ProcessingProcess a medical claim through the financial cycle.1618Published2021-10-01 09:00:00.000000162,164187,188,490,567,955,956,1942,25165 + 167400d467c-b747-4c3d-9631-9648cce5c7c9Medical Facility Account ConsolidationConsolidate financial accounts for a medical facility.1618Published2021-10-01 09:00:00.000000132,134,162,164187,188,490,567,955,956,1942,25164,5 + 168437ee270-5c0c-4c26-a007-77d866acfffcUnbilled Medical Procedure Financial Impact ExplanationExplain the financial impact to a facility given unbilled medical procedures.1618Published2021-10-01 09:00:00.000000132,133,134,162,164,167,168,169,170,171187,188,490,567,955,956,1942,25164,5 + 169b0a3978a-e54e-4089-9564-45c5cf7bac17Accounting Trend AnalysisAnalyze current accounting trends to design models to establish cost-effective budgets for future projects.1728Published2021-10-01 09:00:00.000000132,133,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 170f604b5d2-0fcf-4cbd-830d-5db6d51ea570Cash Flow Report CreationCreate a cash flow report for an organization.1728Published2021-10-01 09:00:00.00000091,132,133,142,173,174,175,176,177,17810,13,30,462,463,558,593,596,618,1464,1465,1466,1467,1468,1469,1473,1500,1501,1502,1503,1504,1505,1506,2509,2513,2514,2515 + 171ac9f004d-4cc2-4149-b395-f02023c13c45Annual Budget DevelopmentDevelop an annual budget for an organization's expenses.1728Published2021-10-01 09:00:00.00000091,132,133,142,173,174,175,176,177,17810,13,30,462,463,558,593,596,618,1464,1465,1466,1467,1468,1469,1473,1500,1501,1502,1503,1504,1505,1506,2509,2513,2514,2515 + 1728a77812d-1983-4639-8c7e-ab74e542f5b8Company-Wide Plan DevelopmentDevelop company-wide plans to reduce financial risks and lower costs that align to generally accepted accounting principles (GAAP) methodologies.1728Published2021-10-01 09:00:00.000000132,134,135,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1730a6fcfde-e53c-4df4-8557-7f8409c3d8f2Company-Wide Plan ImplementationImplement company-wide plans to reduce financial risks and lower costs that align to generally accepted accounting principles (GAAP) methodologies.1728Published2021-10-01 09:00:00.000000132,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 174a2a1fd33-a0fb-4831-9f47-9e260f6a0ac7Anticipated Revenue ForecastingForecast anticipated revenue compared to expenses.1728Published2021-10-01 09:00:00.00000091,132,133,142,173,174,175,176,177,17810,13,30,462,463,558,593,596,618,1464,1465,1466,1467,1468,1469,1473,1500,1501,1502,1503,1504,1505,1506,2509,2513,2514,2515 + 17594ca5450-fb14-4768-883f-1d98abfbae6fProper Accounting Methods EnforcementEnforce proper accounting methods and policies to ensure positive overall company financial health.1728Published2021-10-01 09:00:00.000000132,134,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 17638b32fbd-99b1-41c9-a59c-3e2c9c68c6a9Financial Statement ReviewReview financial statements to identify discrepancies and make corrections.1728Published2021-10-01 09:00:00.000000132,134,135,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 177b8ff2c61-3be8-46df-b088-ba0b9f97c044Cash Flow AnalysisAnalyze cash flows in spreadsheet software using macros for advanced data manipulation.1798Published2021-10-01 09:00:00.000000132,133,134,142,180,181,182,18345,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 178ad0eb9b3-8266-4b1a-87cc-29c68bb19d69General Ledger Entry CreationCreate general ledger entries in accounting and spreadsheet software.1798Published2021-10-01 09:00:00.000000132,142,180,181,182,183,18445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 179903acd86-a7af-4645-b416-a5aa58d8632fTrend Forecast DesigningDesign trend forecasts using accounting software.1798Published2021-10-01 09:00:00.000000132,133,134,135,142,180,182,183,18545,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 180da2555ac-9201-4436-9db6-fc0d8a7e5026Accounting Software Solution EvaluationEvaluate for the best accounting software solution to meet the needs of the organization.1798Published2021-10-01 09:00:00.000000132,134,135,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 18117edf36a-1f31-4c84-9335-9b430b83eba5Accounting Software Solution ImplementationImplement the best accounting software solution to meet the needs of the organization.1798Published2021-10-01 09:00:00.000000132,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 182ae976d9d-8ca2-4620-9e24-2e567d9e4be9Accounting Activities ExecutionExecute accounting activities utilizing applications to meet financial reporting and tax requirements.1798Published2021-10-01 09:00:00.000000132,142,147,180,182,183,186,187,188,189,1909,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 183ddcfed51-77f9-4165-a6aa-34de0cefe39cFinancial Transactions ExportationExport financial transactions using accounting software.1798Published2021-10-01 09:00:00.00000091,132,133,134,135,143,147,148,165,166,180,182,18345,47,49,52,465,559,639,642,644,645,646,647,651 + 1845e50454e-8096-4bc6-8dd4-5162ed8adc60Assets IdentificationIdentify assets, income, and expenses by using an accounting tracking system.1798Published2021-10-01 09:00:00.00000091,132,133,134,135,143,147,148,165,166,180,182,18345,47,49,52,465,559,639,642,644,645,646,647,651 + 1851ca4f89c-0da9-4574-a79a-bfff9b57cc7cSoftware Implementation Process ImprovementImprove accounting software implementation processes to simplify enterprise-wide installation and reduce overall installation time.1798Published2021-10-01 09:00:00.000000132,142,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 1863f04a22e-c9e1-44a3-ad54-f25ca674a1adSoftware Platform Development and Implementation LeadershipLead the development and implementation of a software platform to provide a secure and accurate platform for calculating revenue, cash flow, and payroll.1798Published2021-10-01 09:00:00.000000132,142,180,182,18345,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1879c47b1aa-fe14-4c2f-ae1f-1695b16cdc4dAccounts Payable and Receivable ManagementManage accounts payable and receivable, advanced cost accounting, environmental accounting, and reporting transactions with an accounting software.1798Published2021-10-01 09:00:00.000000132,142,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 188125049c9-c0b8-4559-b936-7209c2c4b337"Centers" Feature of QuickBooks NavigationNavigate the "Centers" feature of QuickBooks to execute various tasks related to customers, including using analysis from insights and setting up charts of accounts.1798Published2021-10-01 09:00:00.000000132,142,180,182,1839,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 189fc82ffa6-a8b6-44ae-b222-51778f84e1c4Double Entry Transactions PerformancePerform double entry transactions and confirms accounts are in balance.1798Published2021-10-01 09:00:00.000000132,180,182,18345,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1903270a66e-7763-442f-bae3-ddf5c8aba8e1Reports to StakeholdersProvide reports to stakeholders using accounting software and core systems.1798Published2021-10-01 09:00:00.00000091,132,133,134,135,143,147,148,165,166,180,182,18345,47,49,465,559,639,642,644,645,646,647 + 19101a10d41-bbe6-413b-9b45-b9eac7bbc7b6Payroll ProcessingRun payroll processing.1798Published2021-10-01 09:00:00.000000132,142,180,182,1839,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 1924a28c05f-e91c-4923-9782-1bb9b6981ad8Strategic Financial Decision RecommendationsApply insights to recommend strategic financial decisions and prepare financial reports for U.S. Securities and Exchange Commission (SEC) filings.1798Published2021-10-01 09:00:00.000000132,133,142,180,182,1839,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 193d30c8a27-93ea-420c-89a1-e1d0497ff014General Ledger Codes AssignmentAssign unique general ledger codes to each account within an accounting system.1918Published2021-10-01 09:00:00.000000132,142,143,147,192,193,194,195,19635,45,47,48,49,50,52,464,465,559,626,639,642,643,644,645,646,647,648,651 + 19495851275-eb69-4419-957a-2e1ca586350dDesign Features DevelopmentDevelop design features for the business accounting system to support business objectives.1918Published2021-10-01 09:00:00.000000132,133,192,1969,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 1952c1c5d29-ffe5-439e-97b8-70e8a818fca8Financial Statement GenerationGenerate financial statements for submission to regulatory agencies.1918Published2021-10-01 09:00:00.000000132,142,143,147,192,193,194,195,19635,45,47,48,49,50,52,464,465,559,626,639,642,643,644,645,646,647,648,651 + 19674c06473-35f9-4002-91ea-990377bb7baaBasic Accounting Process IdentificationIdentify basic accounting processes and systems within a structured environment to meet a limited need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 1971f7b45a1-8827-4c2c-990a-c5e51fe97a1dFunction ImplementationImplement customizable general business accounting functions into an integrated management information system to increase efficiency of the enterprise accounting system.1918Published2021-10-01 09:00:00.000000132,133,192,1969,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 198e9737bcd-0dcc-48af-a67c-9a06c7890c2bAccounting Systems MonitoringMonitor accounting systems to ensure compliance with organizational and federal guidelines.1918Published2021-10-01 09:00:00.000000132,134,192,1969,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 + 199524de3d9-5529-4bb3-aa7d-d9229a3b34adFinancial Data UploadingUpload financial data into accounting systems to generate monthly reports.1918Published2021-10-01 09:00:00.000000132,142,143,147,192,193,194,195,19635,45,47,48,49,50,52,464,465,559,626,639,642,643,644,645,646,647,648,651 + 20057c3889f-53a5-48ca-b02c-ccf9b50a6481Advanced Accounting Process ApplicationApply advanced accounting processes and systems within a broad environment to meet an organizational need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 2018056a96e-9136-401e-8b07-7330e84071e7Appropriate Accounting Process DeploymentDeploy appropriate accounting processes and systems within a limited environment to meet a routine need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 202af2b9424-cdf2-4a1f-a8f8-1281eb477d5eComplex Accounting Process ExecutionExecute complex accounting processes and systems within a wide environment to meet an organizational need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 90bb6a57c6-0779-46c7-b64a-0f6bb7827e70Determine Acceptance Testing DiscrepanciesDetermine if there are discrepancies between original software specifications and final acceptance testing scenarios.898Published2021-10-01 09:00:00.00000090,90,92,92,107,10754,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493,54,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 + 9473ec441f-7c07-42d2-98c8-c8461e7f7c38User Experience Acceptance Test DesignDesign alterations to user experience components to meet acceptance testing criteria.898Published2021-10-01 09:00:00.00000090,90,92,92,110,110,111,11158,466,560,667,2494,58,466,560,667,2494 + 10378d61a82-8302-488c-9c3f-bf01d88e5ff9Network Router Security MonitoringMonitor network routers for security issues.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,124,12456,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 104f5b83170-bff2-4bff-93eb-660a2a9f6653Network Routers Security ConfigurationConfigure security on network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,125,12556,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 105b749ad2f-465a-41a3-92be-ba7072ce09b2Router Network Traffic ConfigurationConfigure network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,119,122,122,122,125,125,125,126,126,12656,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 105b749ad2f-465a-41a3-92be-ba7072ce09b2Router Network Traffic ConfigurationConfigure network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,119,122,122,122,125,125,125,126,126,12656,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 106a3fe184d-921a-45f6-a384-308ca77b4498Network Connection DesignDesign a network connection between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,127,127,128,12856,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 + 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 + 46a02ac8d-2e00-4fac-8fde-1f8237bdd769Large-Scale Web Application BuildBuild large-scale web applications using the .NET Framework with minimum coding.18Published2021-10-01 09:00:00.0000002,2,7,7,9,955,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 + 55cef80ee-5799-4f5c-89e5-8e4908419a50Service-Oriented Application BuildBuild service-oriented applications using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,7,7,10,1055,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 + 670b1fe1b-ecf1-4ca8-88ee-311d4d93ca67Application Domain CreationCreate application domains and assemblies using attributes, formatting and parsing base types, collections, events and exceptions, files and data streams, and generics.18Published2021-10-01 09:00:00.0000002,2,3,3,7,755,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 + 70a79c4b2-a715-4596-8211-b57e7e9e791aWindows-Based Application CreationCreate Windows-based applications using the .NET framework.18Published2021-10-01 09:00:00.0000002,2,7,7,11,1155,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 + 8c396acc6-9f88-484f-935d-8dbf9488c428Geometric Primitive Shape CombinationCombine geometric primitive shapes into digital 3D representations of a component of an object.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 + 9d59223d2-7a38-4146-8f4e-f226262bc2afGraphical Representation CreationCreate a 3D graphical representation of a physical object using specialized software.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 + 10ca32343a-1df3-4cb3-aa90-5dd6290ab248Layered Component IdentificationIdentify the layered components of a physical object that make up the complete digital three-dimensional (3D) rendering.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 + 117c9aff0f-0f53-4f92-b867-afe080da54a9System DesignDesign systems that facilitate trust and improved performance.208Published2021-10-01 09:00:00.00000021,21,22,2236,464,559,627,1521,36,464,559,627,1521 + 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 + + diff --git a/api/src/test/resources/mock-data.xml b/api/src/test/resources/mock-data.xml index 8eaa862f5..76fc4221a 100644 --- a/api/src/test/resources/mock-data.xml +++ b/api/src/test/resources/mock-data.xml @@ -632,13 +632,13 @@ 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 - 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778user@email.com - 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378user@email.com - 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078user@email.com - 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778user@email.com - 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688user@email.com - 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538user@email.com - 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548user@email.com + 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778 + 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 + 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 + 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 + 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 + 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538 + 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 From 4c904e141aa038e25fe4895533ffca5cd3c765bd Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 9 Feb 2023 17:15:16 -0600 Subject: [PATCH 044/150] reverting mock-data xml file --- .../osmt/collection/CollectionController.kt | 3 +- .../kotlin/edu/wgu/osmt/config/Constants.kt | 1 + api/src/test/resources/mock-data-v2.xml | 875 ------------------ api/src/test/resources/mock-data.xml | 15 +- 4 files changed, 11 insertions(+), 883 deletions(-) delete mode 100644 api/src/test/resources/mock-data-v2.xml diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt index d9345bb95..deac351bc 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt @@ -13,6 +13,7 @@ import edu.wgu.osmt.auditlog.AuditLog import edu.wgu.osmt.auditlog.AuditLogRepository import edu.wgu.osmt.auditlog.AuditLogSortEnum import edu.wgu.osmt.config.AppConfig +import edu.wgu.osmt.config.DEFAULT_WORKSPACE_NAME import edu.wgu.osmt.db.PublishStatus import edu.wgu.osmt.elasticsearch.OffsetPageable import edu.wgu.osmt.richskill.RichSkillRepository @@ -217,7 +218,7 @@ class CollectionController @Autowired constructor( } ?: collectionRepository.createFromApi( listOf( ApiCollectionUpdate( - "defaultWorkspace", + DEFAULT_WORKSPACE_NAME, PublishStatus.Workspace, oAuthHelper.readableUsername(user), ApiStringListUpdate() diff --git a/api/src/main/kotlin/edu/wgu/osmt/config/Constants.kt b/api/src/main/kotlin/edu/wgu/osmt/config/Constants.kt index 3b5332703..1212728a9 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/config/Constants.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/config/Constants.kt @@ -2,6 +2,7 @@ package edu.wgu.osmt.config const val UNAUTHENTICATED_USERNAME = "unauthenticated" const val QUOTED_SEARCH_REGEX_PATTERN = "([\"\'])(?:(?=(\\\\?))\\2.)*?\\1" +const val DEFAULT_WORKSPACE_NAME = "My Workspace" // API parameter constants const val CATEGORY_ASC = "name.asc" diff --git a/api/src/test/resources/mock-data-v2.xml b/api/src/test/resources/mock-data-v2.xml deleted file mode 100644 index 26641159a..000000000 --- a/api/src/test/resources/mock-data-v2.xml +++ /dev/null @@ -1,875 +0,0 @@ - - - 552021-06-14 14:35:07.816233Computer and Information Research Scientists15-1220bls - 582021-06-14 14:35:08.150119Software and Web Developers, Programmers, and Testers15-1250bls - 592021-06-14 14:35:08.264118Miscellaneous Computer Occupations15-1290bls - 4662021-06-14 14:35:42.920525Computer Occupations15-1200bls - 5602021-06-14 14:35:50.697073Computer and Mathematical Occupations15-0000bls - 6562021-06-14 14:36:07.538865Computer and Mathematical OccupationsComputer OccupationsComputer and Information Research ScientistsComputer and Information Research Scientists15-1221Computer and Information Research Scientistsbls - 6632021-06-14 14:36:08.981137Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersComputer Programmers15-1251Computer Programmersbls - 6642021-06-14 14:36:09.163140Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersSoftware Developers15-1252Software Developersbls - 6652021-06-14 14:36:09.374136Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersSoftware Quality Assurance Analysts and Testers15-1253Software Quality Assurance Analysts and Testersbls - 6662021-06-14 14:36:09.580135Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersWeb Developers15-1254Web Developersbls - 6672021-06-14 14:36:09.756142Computer and Mathematical OccupationsComputer OccupationsSoftware and Web Developers, Programmers, and TestersWeb and Digital Interface Designers15-1255Web and Digital Interface Designersbls - 6682021-06-14 14:36:09.933680Computer and Mathematical OccupationsComputer OccupationsMiscellaneous Computer OccupationsComputer Occupations, All Other15-1299Computer Occupations, All Otherbls - 832021-06-14 14:35:10.335862Miscellaneous Engineers17-2190bls - 4692021-06-14 14:35:43.132983Engineers17-2000bls - 5612021-06-14 14:35:50.772069Architecture and Engineering Occupations17-0000bls - 6962021-06-14 14:36:15.237783Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199Engineers, All Otherbls - 16262021-06-14 14:41:00.763365Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.00Engineers, All OtherAll engineers not listed separately.o*net - 16272021-06-14 14:41:00.950419Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.03Energy Engineers, Except Wind and SolarDesign, develop, or evaluate energy-related projects or programs to reduce energy costs or improve energy efficiency during the designing, building, or remodeling stages of construction. May specialize in electrical systems; heating, ventilation, and air-conditioning (HVAC) systems; green buildings; lighting; air quality; or energy procurement.o*net - 16282021-06-14 14:41:01.168416Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.05Mechatronics EngineersResearch, design, develop, or test automation, intelligent systems, smart devices, or industrial systems control.o*net - 16292021-06-14 14:41:01.308422Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.06Microsystems EngineersResearch, design, develop, or test microelectromechanical systems (MEMS) devices.o*net - 16302021-06-14 14:41:01.470948Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.07Photonics EngineersDesign technologies specializing in light information or light energy, such as laser or fiber optics technology.o*net - 16312021-06-14 14:41:01.600983Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.08Robotics EngineersResearch, design, develop, or test robotic applications.o*net - 16322021-06-14 14:41:01.717984Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.09Nanosystems EngineersDesign, develop, or supervise the production of materials, devices, or systems of unique molecular or macromolecular composition, applying principles of nanoscale physics and electrical, chemical, or biological engineering.o*net - 16332021-06-14 14:41:01.828033Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.10Wind Energy EngineersDesign underground or overhead wind farm collector systems and prepare and develop site specifications.o*net - 16342021-06-14 14:41:01.951999Architecture and Engineering OccupationsEngineersMiscellaneous EngineersEngineers, All Other17-2199.11Solar Energy Systems EngineersPerform site-specific engineering analysis or evaluation of energy efficiency and solar projects involving residential, commercial, or industrial customers. Design solar domestic hot water and space heating systems for new and existing structures, applying knowledge of structural energy requirements, local climates, solar technology, and thermodynamics.o*net - 24642021-06-14 14:43:16.18997717-2199.01 - 24652021-06-14 14:43:16.26429117-2199.02 - 24662021-06-14 14:43:16.32727817-2199.04 - 362021-06-14 14:35:05.937825Human Resources Workers13-1070bls - 4642021-06-14 14:35:42.779495Business Operations Specialists13-1000bls - 5592021-06-14 14:35:50.629074Business and Financial Operations Occupations13-0000bls - 6272021-06-14 14:36:01.870292Business and Financial Operations OccupationsBusiness Operations SpecialistsHuman Resources WorkersHuman Resources Specialists13-1071Human Resources Specialistsbls - 15212021-06-14 14:40:47.349382Business and Financial Operations OccupationsBusiness Operations SpecialistsHuman Resources WorkersHuman Resources Specialists13-1071.00Human Resources SpecialistsRecruit, screen, interview, or place individuals within an organization. May perform other activities in multiple human resources areas.o*net - 1432021-06-14 14:35:15.618938Librarians and Media Collections Specialists25-4020bls - 1462021-06-14 14:35:15.839679Instructional Coordinators25-9030bls - 1482021-06-14 14:35:16.012678Miscellaneous Educational Instruction and Library Workers25-9090bls - 4832021-06-14 14:35:44.269576Librarians, Curators, and Archivists25-4000bls - 4842021-06-14 14:35:44.345570Other Educational Instruction and Library Occupations25-9000bls - 5652021-06-14 14:35:51.039073Educational Instruction and Library Occupations25-0000bls - 8432021-06-14 14:36:44.195876Educational Instruction and Library OccupationsLibrarians, Curators, and ArchivistsLibrarians and Media Collections SpecialistsLibrarians and Media Collections Specialists25-4022Librarians and Media Collections Specialistsbls - 8462021-06-14 14:36:44.764330Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsInstructional CoordinatorsInstructional Coordinators25-9031Instructional Coordinatorsbls - 8512021-06-14 14:36:45.647883Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsMiscellaneous Educational Instruction and Library WorkersEducational Instruction and Library Workers, All Other25-9099Educational Instruction and Library Workers, All Otherbls - 18082021-06-14 14:41:22.978010Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsInstructional CoordinatorsInstructional Coordinators25-9031.00Instructional CoordinatorsDevelop instructional material, coordinate educational content, and incorporate current technology into instruction in order to provide guidelines to educators and instructors for developing curricula and conducting courses. May train and coach teachers. Includes educational consultants and specialists, and instructional material directors.o*net - 18132021-06-14 14:41:23.716104Educational Instruction and Library OccupationsOther Educational Instruction and Library OccupationsMiscellaneous Educational Instruction and Library WorkersEducational Instruction and Library Workers, All Other25-9099.00Educational Instruction and Library Workers, All OtherAll educational instruction and library workers not listed separately.o*net - 24672021-06-14 14:43:18.13508125-9011 - 24682021-06-14 14:43:18.18505025-9011.00 - 24692021-06-14 14:43:18.23704825-9031.01 - 1232021-06-14 14:35:13.879463Math and Computer Science Teachers, Postsecondary25-1020bls - 1252021-06-14 14:35:14.050352Life Sciences Teachers, Postsecondary25-1040bls - 1262021-06-14 14:35:14.130683Physical Sciences Teachers, Postsecondary25-1050bls - 1292021-06-14 14:35:14.405516Education and Library Science Teachers, Postsecondary25-1080bls - 1342021-06-14 14:35:14.860508Elementary and Middle School Teachers25-2020bls - 1352021-06-14 14:35:14.935266Secondary School Teachers25-2030bls - 1362021-06-14 14:35:15.014270Special Education Teachers25-2050bls - 4802021-06-14 14:35:44.014573Postsecondary Teachers25-1000bls - 4812021-06-14 14:35:44.123566Preschool, Elementary, Middle, Secondary, and Special Education Teachers25-2000bls - 7862021-06-14 14:36:33.019169Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryComputer Science Teachers, Postsecondary25-1021Computer Science Teachers, Postsecondarybls - 7872021-06-14 14:36:33.223730Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryMathematical Science Teachers, Postsecondary25-1022Mathematical Science Teachers, Postsecondarybls - 7902021-06-14 14:36:33.763445Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryAgricultural Sciences Teachers, Postsecondary25-1041Agricultural Sciences Teachers, Postsecondarybls - 7912021-06-14 14:36:33.934452Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryBiological Science Teachers, Postsecondary25-1042Biological Science Teachers, Postsecondarybls - 7922021-06-14 14:36:34.167554Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryForestry and Conservation Science Teachers, Postsecondary25-1043Forestry and Conservation Science Teachers, Postsecondarybls - 7932021-06-14 14:36:34.329559Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryAtmospheric, Earth, Marine, and Space Sciences Teachers, Postsecondary25-1051Atmospheric, Earth, Marine, and Space Sciences Teachers, Postsecondarybls - 7942021-06-14 14:36:34.555592Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryChemistry Teachers, Postsecondary25-1052Chemistry Teachers, Postsecondarybls - 7952021-06-14 14:36:34.768202Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryEnvironmental Science Teachers, Postsecondary25-1053Environmental Science Teachers, Postsecondarybls - 7962021-06-14 14:36:34.947255Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryPhysics Teachers, Postsecondary25-1054Physics Teachers, Postsecondarybls - 8072021-06-14 14:36:37.178871Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryEducation Teachers, Postsecondary25-1081Education Teachers, Postsecondarybls - 8082021-06-14 14:36:37.349869Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryLibrary Science Teachers, Postsecondary25-1082Library Science Teachers, Postsecondarybls - 8242021-06-14 14:36:40.350773Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersElementary School Teachers, Except Special Education25-2021Elementary School Teachers, Except Special Educationbls - 8252021-06-14 14:36:40.577300Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersMiddle School Teachers, Except Special and Career/Technical Education25-2022Middle School Teachers, Except Special and Career/Technical Educationbls - 8262021-06-14 14:36:40.736304Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersCareer/Technical Education Teachers, Middle School25-2023Career/Technical Education Teachers, Middle Schoolbls - 8272021-06-14 14:36:40.911865Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersSecondary School Teachers, Except Special and Career/Technical Education25-2031Secondary School Teachers, Except Special and Career/Technical Educationbls - 8282021-06-14 14:36:41.120863Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersCareer/Technical Education Teachers, Secondary School25-2032Career/Technical Education Teachers, Secondary Schoolbls - 8292021-06-14 14:36:41.291860Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Preschool25-2051Special Education Teachers, Preschoolbls - 8302021-06-14 14:36:41.511830Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Kindergarten25-2055Special Education Teachers, Kindergartenbls - 8312021-06-14 14:36:41.844828Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Elementary School25-2056Special Education Teachers, Elementary Schoolbls - 8322021-06-14 14:36:42.084830Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Middle School25-2057Special Education Teachers, Middle Schoolbls - 8332021-06-14 14:36:42.276837Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Secondary School25-2058Special Education Teachers, Secondary Schoolbls - 8342021-06-14 14:36:42.527828Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, All Other25-2059Special Education Teachers, All Otherbls - 17472021-06-14 14:41:15.676973Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryComputer Science Teachers, Postsecondary25-1021.00Computer Science Teachers, PostsecondaryTeach courses in computer science. May specialize in a field of computer science, such as the design and function of computers or operations and research analysis. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17482021-06-14 14:41:15.779980Educational Instruction and Library OccupationsPostsecondary TeachersMath and Computer Science Teachers, PostsecondaryMathematical Science Teachers, Postsecondary25-1022.00Mathematical Science Teachers, PostsecondaryTeach courses pertaining to mathematical concepts, statistics, and actuarial science and to the application of original and standardized mathematical techniques in solving specific problems and situations. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17512021-06-14 14:41:16.133977Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryAgricultural Sciences Teachers, Postsecondary25-1041.00Agricultural Sciences Teachers, PostsecondaryTeach courses in the agricultural sciences. Includes teachers of agronomy, dairy sciences, fisheries management, horticultural sciences, poultry sciences, range management, and agricultural soil conservation. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17522021-06-14 14:41:16.240977Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryBiological Science Teachers, Postsecondary25-1042.00Biological Science Teachers, PostsecondaryTeach courses in biological sciences. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17532021-06-14 14:41:16.341978Educational Instruction and Library OccupationsPostsecondary TeachersLife Sciences Teachers, PostsecondaryForestry and Conservation Science Teachers, Postsecondary25-1043.00Forestry and Conservation Science Teachers, PostsecondaryTeach courses in forestry and conservation science. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17542021-06-14 14:41:16.473976Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryAtmospheric, Earth, Marine, and Space Sciences Teachers, Postsecondary25-1051.00Atmospheric, Earth, Marine, and Space Sciences Teachers, PostsecondaryTeach courses in the physical sciences, except chemistry and physics. Includes both teachers primarily engaged in teaching, and those who do a combination of teaching and research.o*net - 17552021-06-14 14:41:16.583011Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryChemistry Teachers, Postsecondary25-1052.00Chemistry Teachers, PostsecondaryTeach courses pertaining to the chemical and physical properties and compositional changes of substances. Work may include providing instruction in the methods of qualitative and quantitative chemical analysis. Includes both teachers primarily engaged in teaching, and those who do a combination of teaching and research.o*net - 17562021-06-14 14:41:16.693662Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryEnvironmental Science Teachers, Postsecondary25-1053.00Environmental Science Teachers, PostsecondaryTeach courses in environmental science. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17572021-06-14 14:41:16.806212Educational Instruction and Library OccupationsPostsecondary TeachersPhysical Sciences Teachers, PostsecondaryPhysics Teachers, Postsecondary25-1054.00Physics Teachers, PostsecondaryTeach courses pertaining to the laws of matter and energy. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17682021-06-14 14:41:18.284611Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryEducation Teachers, Postsecondary25-1081.00Education Teachers, PostsecondaryTeach courses pertaining to education, such as counseling, curriculum, guidance, instruction, teacher education, and teaching English as a second language. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17692021-06-14 14:41:18.395631Educational Instruction and Library OccupationsPostsecondary TeachersEducation and Library Science Teachers, PostsecondaryLibrary Science Teachers, Postsecondary25-1082.00Library Science Teachers, PostsecondaryTeach courses in library science. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17852021-06-14 14:41:20.206382Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersElementary School Teachers, Except Special Education25-2021.00Elementary School Teachers, Except Special EducationTeach academic and social skills to students at the elementary school level.o*net - 17862021-06-14 14:41:20.330615Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersMiddle School Teachers, Except Special and Career/Technical Education25-2022.00Middle School Teachers, Except Special and Career/Technical EducationTeach one or more subjects to students at the middle, intermediate, or junior high school level.o*net - 17872021-06-14 14:41:20.439639Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersElementary and Middle School TeachersCareer/Technical Education Teachers, Middle School25-2023.00Career/Technical Education Teachers, Middle SchoolTeach occupational, vocational, career, or technical subjects to students at the middle, intermediate, or junior high school level.o*net - 17882021-06-14 14:41:20.547611Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersSecondary School Teachers, Except Special and Career/Technical Education25-2031.00Secondary School Teachers, Except Special and Career/Technical EducationTeach one or more subjects to students at the secondary school level.o*net - 17892021-06-14 14:41:20.652610Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSecondary School TeachersCareer/Technical Education Teachers, Secondary School25-2032.00Career/Technical Education Teachers, Secondary SchoolTeach occupational, vocational, career, or technical subjects to students at the secondary school level.o*net - 17902021-06-14 14:41:20.761654Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, Preschool25-2051.00Special Education Teachers, PreschoolTeach academic, social, and life skills to preschool-aged students with learning, emotional, or physical disabilities. Includes teachers who specialize and work with students who are blind or have visual impairments; students who are deaf or have hearing impairments; and students with intellectual disabilities.o*net - 17952021-06-14 14:41:21.351396Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, All Other25-2059.00Special Education Teachers, All OtherAll special education teachers not listed separately.o*net - 17962021-06-14 14:41:21.483396Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersSpecial Education TeachersSpecial Education Teachers, All Other25-2059.01Adapted Physical Education SpecialistsProvide individualized physical education instruction or services to children, youth, or adults with exceptional physical needs due to gross motor developmental delays or other impairments.o*net - 24702021-06-14 14:43:18.61349525-2052.00 - 24712021-06-14 14:43:18.66351625-2053.00 - 24722021-06-14 14:43:18.70749325-2054.00 - 1332021-06-14 14:35:14.786512Preschool and Kindergarten Teachers25-2010bls - 8222021-06-14 14:36:40.003644Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersPreschool Teachers, Except Special Education25-2011Preschool Teachers, Except Special Educationbls - 8232021-06-14 14:36:40.181432Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersKindergarten Teachers, Except Special Education25-2012Kindergarten Teachers, Except Special Educationbls - 17832021-06-14 14:41:19.969383Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersPreschool Teachers, Except Special Education25-2011.00Preschool Teachers, Except Special EducationInstruct preschool-aged students, following curricula or lesson plans, in activities designed to promote social, physical, and intellectual growth.o*net - 17842021-06-14 14:41:20.091378Educational Instruction and Library OccupationsPreschool, Elementary, Middle, Secondary, and Special Education TeachersPreschool and Kindergarten TeachersKindergarten Teachers, Except Special Education25-2012.00Kindergarten Teachers, Except Special EducationTeach academic and social skills to kindergarten students.o*net - 1372021-06-14 14:35:15.091266Adult Basic Education, Adult Secondary Education, and English as a Second Language Instructors25-3010bls - 4822021-06-14 14:35:44.197570Other Teachers and Instructors25-3000bls - 5842021-06-14 14:35:53.352438Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersAdvertising and Promotions ManagersAdvertising and Promotions Managers11-2011Advertising and Promotions Managersbls - 5852021-06-14 14:35:53.603438Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersMarketing Managers11-2021Marketing Managersbls - 5862021-06-14 14:35:53.805439Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersSales Managers11-2022Sales Managersbls - 6372021-06-14 14:36:04.054137Business and Financial Operations OccupationsBusiness Operations SpecialistsMarket Research Analysts and Marketing SpecialistsMarket Research Analysts and Marketing Specialists13-1161Market Research Analysts and Marketing Specialistsbls - 6552021-06-14 14:36:07.280337Computer and Mathematical OccupationsComputer OccupationsComputer and Information AnalystsInformation Security Analysts15-1212Information Security Analystsbls - 17972021-06-14 14:41:21.590398Educational Instruction and Library OccupationsOther Teachers and InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language Instructors25-3011.00Adult Basic Education, Adult Secondary Education, and English as a Second Language InstructorsTeach or instruct out-of-school youths and adults in basic education, literacy, or English as a Second Language classes, or in classes for earning a high school equivalency credential.o*net - 8352021-06-14 14:36:42.698831Educational Instruction and Library OccupationsOther Teachers and InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language InstructorsAdult Basic Education, Adult Secondary Education, and English as a Second Language Instructors25-3011Adult Basic Education, Adult Secondary Education, and English as a Second Language Instructorsbls - 1222021-06-14 14:35:13.775455Business Teachers, Postsecondary25-1010bls - 1272021-06-14 14:35:14.220690Social Sciences Teachers, Postsecondary25-1060bls - 1282021-06-14 14:35:14.303507Health Teachers, Postsecondary25-1070bls - 1312021-06-14 14:35:14.610505Arts, Communications, History, and Humanities Teachers, Postsecondary25-1120bls - 7852021-06-14 14:36:32.836207Educational Instruction and Library OccupationsPostsecondary TeachersBusiness Teachers, PostsecondaryBusiness Teachers, Postsecondary25-1011Business Teachers, Postsecondarybls - 7972021-06-14 14:36:35.111285Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryAnthropology and Archeology Teachers, Postsecondary25-1061Anthropology and Archeology Teachers, Postsecondarybls - 7982021-06-14 14:36:35.288844Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryArea, Ethnic, and Cultural Studies Teachers, Postsecondary25-1062Area, Ethnic, and Cultural Studies Teachers, Postsecondarybls - 7992021-06-14 14:36:35.490822Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryEconomics Teachers, Postsecondary25-1063Economics Teachers, Postsecondarybls - 8002021-06-14 14:36:35.674830Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryGeography Teachers, Postsecondary25-1064Geography Teachers, Postsecondarybls - 8012021-06-14 14:36:35.853826Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPolitical Science Teachers, Postsecondary25-1065Political Science Teachers, Postsecondarybls - 8022021-06-14 14:36:36.033821Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPsychology Teachers, Postsecondary25-1066Psychology Teachers, Postsecondarybls - 8032021-06-14 14:36:36.307824Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySociology Teachers, Postsecondary25-1067Sociology Teachers, Postsecondarybls - 8042021-06-14 14:36:36.614824Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySocial Sciences Teachers, Postsecondary, All Other25-1069Social Sciences Teachers, Postsecondary, All Otherbls - 8052021-06-14 14:36:36.809822Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryHealth Specialties Teachers, Postsecondary25-1071Health Specialties Teachers, Postsecondarybls - 8062021-06-14 14:36:36.983350Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryNursing Instructors and Teachers, Postsecondary25-1072Nursing Instructors and Teachers, Postsecondarybls - 8122021-06-14 14:36:38.101868Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryArt, Drama, and Music Teachers, Postsecondary25-1121Art, Drama, and Music Teachers, Postsecondarybls - 8132021-06-14 14:36:38.301866Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryCommunications Teachers, Postsecondary25-1122Communications Teachers, Postsecondarybls - 8142021-06-14 14:36:38.497867Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryEnglish Language and Literature Teachers, Postsecondary25-1123English Language and Literature Teachers, Postsecondarybls - 8152021-06-14 14:36:38.693918Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryForeign Language and Literature Teachers, Postsecondary25-1124Foreign Language and Literature Teachers, Postsecondarybls - 8162021-06-14 14:36:38.875920Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryHistory Teachers, Postsecondary25-1125History Teachers, Postsecondarybls - 8172021-06-14 14:36:39.035525Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryPhilosophy and Religion Teachers, Postsecondary25-1126Philosophy and Religion Teachers, Postsecondarybls - 17462021-06-14 14:41:15.569972Educational Instruction and Library OccupationsPostsecondary TeachersBusiness Teachers, PostsecondaryBusiness Teachers, Postsecondary25-1011.00Business Teachers, PostsecondaryTeach courses in business administration and management, such as accounting, finance, human resources, labor and industrial relations, marketing, and operations research. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17582021-06-14 14:41:16.923279Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryAnthropology and Archeology Teachers, Postsecondary25-1061.00Anthropology and Archeology Teachers, PostsecondaryTeach courses in anthropology or archeology. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17592021-06-14 14:41:17.071270Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryArea, Ethnic, and Cultural Studies Teachers, Postsecondary25-1062.00Area, Ethnic, and Cultural Studies Teachers, PostsecondaryTeach courses pertaining to the culture and development of an area, an ethnic group, or any other group, such as Latin American studies, women's studies, or urban affairs. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17602021-06-14 14:41:17.206271Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryEconomics Teachers, Postsecondary25-1063.00Economics Teachers, PostsecondaryTeach courses in economics. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17612021-06-14 14:41:17.331270Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryGeography Teachers, Postsecondary25-1064.00Geography Teachers, PostsecondaryTeach courses in geography. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17622021-06-14 14:41:17.475611Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPolitical Science Teachers, Postsecondary25-1065.00Political Science Teachers, PostsecondaryTeach courses in political science, international affairs, and international relations. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17632021-06-14 14:41:17.614613Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondaryPsychology Teachers, Postsecondary25-1066.00Psychology Teachers, PostsecondaryTeach courses in psychology, such as child, clinical, and developmental psychology, and psychological counseling. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17642021-06-14 14:41:17.742611Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySociology Teachers, Postsecondary25-1067.00Sociology Teachers, PostsecondaryTeach courses in sociology. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17652021-06-14 14:41:17.881616Educational Instruction and Library OccupationsPostsecondary TeachersSocial Sciences Teachers, PostsecondarySocial Sciences Teachers, Postsecondary, All Other25-1069.00Social Sciences Teachers, Postsecondary, All OtherAll postsecondary social sciences teachers not listed separately.o*net - 17662021-06-14 14:41:18.020614Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryHealth Specialties Teachers, Postsecondary25-1071.00Health Specialties Teachers, PostsecondaryTeach courses in health specialties, in fields such as dentistry, laboratory technology, medicine, pharmacy, public health, therapy, and veterinary medicine.o*net - 17672021-06-14 14:41:18.151610Educational Instruction and Library OccupationsPostsecondary TeachersHealth Teachers, PostsecondaryNursing Instructors and Teachers, Postsecondary25-1072.00Nursing Instructors and Teachers, PostsecondaryDemonstrate and teach patient care in classroom and clinical units to nursing students. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17732021-06-14 14:41:18.859666Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryArt, Drama, and Music Teachers, Postsecondary25-1121.00Art, Drama, and Music Teachers, PostsecondaryTeach courses in drama, music, and the arts including fine and applied art, such as painting and sculpture, or design and crafts. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17742021-06-14 14:41:18.969660Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryCommunications Teachers, Postsecondary25-1122.00Communications Teachers, PostsecondaryTeach courses in communications, such as organizational communications, public relations, radio/television broadcasting, and journalism. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17752021-06-14 14:41:19.076180Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryEnglish Language and Literature Teachers, Postsecondary25-1123.00English Language and Literature Teachers, PostsecondaryTeach courses in English language and literature, including linguistics and comparative literature. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17762021-06-14 14:41:19.193178Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryForeign Language and Literature Teachers, Postsecondary25-1124.00Foreign Language and Literature Teachers, PostsecondaryTeach languages and literature courses in languages other than English. Includes teachers of American Sign Language (ASL). Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17772021-06-14 14:41:19.322181Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryHistory Teachers, Postsecondary25-1125.00History Teachers, PostsecondaryTeach courses in human history and historiography. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 17782021-06-14 14:41:19.428201Educational Instruction and Library OccupationsPostsecondary TeachersArts, Communications, History, and Humanities Teachers, PostsecondaryPhilosophy and Religion Teachers, Postsecondary25-1126.00Philosophy and Religion Teachers, PostsecondaryTeach courses in philosophy, religion, and theology. Includes both teachers primarily engaged in teaching and those who do a combination of teaching and research.o*net - 1742021-06-14 14:35:18.271793Registered Nurses29-1140bls - 4892021-06-14 14:35:44.770602Healthcare Diagnosing or Treating Practitioners29-1000bls - 5672021-06-14 14:35:51.191070Healthcare Practitioners and Technical Occupations29-0000bls - 9132021-06-14 14:36:57.334513Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141Registered Nursesbls - 18832021-06-14 14:41:31.742171Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.00Registered NursesAssess patient health problems and needs, develop and implement nursing care plans, and maintain medical records. Administer nursing care to ill, injured, convalescent, or disabled patients. May advise patients on health maintenance and disease prevention or provide case management. Licensing or registration required.o*net - 18842021-06-14 14:41:31.853172Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.01Acute Care NursesProvide advanced nursing care for patients with acute conditions such as heart attacks, respiratory distress syndrome, or shock. May care for pre- and post-operative patients or perform advanced, invasive diagnostic or therapeutic procedures.o*net - 18852021-06-14 14:41:31.956175Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.02Advanced Practice Psychiatric NursesAssess, diagnose, and treat individuals and families with mental health or substance use disorders or the potential for such disorders. Apply therapeutic activities, including the prescription of medication, per state regulations, and the administration of psychotherapy.o*net - 18862021-06-14 14:41:32.054172Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.03Critical Care NursesProvide specialized nursing care for patients in critical or coronary care units.o*net - 18872021-06-14 14:41:32.149173Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersRegistered NursesRegistered Nurses29-1141.04Clinical Nurse SpecialistsDirect nursing staff in the provision of patient care in a clinical practice setting, such as a hospital, hospice, clinic, or home. Ensure adherence to established clinical policies, protocols, regulations, and standards.o*net - 542021-06-14 14:35:07.720267Computer and Information Analysts15-1210bls - 382021-06-14 14:35:06.135823Management Analysts13-1110bls - 432021-06-14 14:35:06.683829Market Research Analysts and Marketing Specialists13-1160bls - 6322021-06-14 14:36:02.838134Business and Financial Operations OccupationsBusiness Operations SpecialistsManagement AnalystsManagement Analysts13-1111Management Analystsbls - 6542021-06-14 14:36:07.109340Computer and Mathematical OccupationsComputer OccupationsComputer and Information AnalystsComputer Systems Analysts15-1211Computer Systems Analystsbls - 852021-06-14 14:35:10.541855Engineering Technologists and Technicians, Except Drafters17-3020bls - 4702021-06-14 14:35:43.196989Drafters, Engineering Technicians, and Mapping Technicians17-3000bls - 7012021-06-14 14:36:16.157401Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersAerospace Engineering and Operations Technologists and Technicians17-3021Aerospace Engineering and Operations Technologists and Techniciansbls - 7022021-06-14 14:36:16.322441Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersCivil Engineering Technologists and Technicians17-3022Civil Engineering Technologists and Techniciansbls - 7032021-06-14 14:36:16.537416Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectrical and Electronic Engineering Technologists and Technicians17-3023Electrical and Electronic Engineering Technologists and Techniciansbls - 7042021-06-14 14:36:16.713401Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectro-Mechanical and Mechatronics Technologists and Technicians17-3024Electro-Mechanical and Mechatronics Technologists and Techniciansbls - 7052021-06-14 14:36:16.891424Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEnvironmental Engineering Technologists and Technicians17-3025Environmental Engineering Technologists and Techniciansbls - 7062021-06-14 14:36:17.075524Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersIndustrial Engineering Technologists and Technicians17-3026Industrial Engineering Technologists and Techniciansbls - 7072021-06-14 14:36:17.242523Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersMechanical Engineering Technologists and Technicians17-3027Mechanical Engineering Technologists and Techniciansbls - 7082021-06-14 14:36:17.446525Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersCalibration Technologists and Technicians17-3028Calibration Technologists and Techniciansbls - 7092021-06-14 14:36:17.681532Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029Engineering Technologists and Technicians, Except Drafters, All Otherbls - 16392021-06-14 14:41:02.611002Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersAerospace Engineering and Operations Technologists and Technicians17-3021.00Aerospace Engineering and Operations Technologists and TechniciansOperate, install, adjust, and maintain integrated computer/communications systems, consoles, simulators, and other data acquisition, test, and measurement instruments and equipment, which are used to launch, track, position, and evaluate air and space vehicles. May record and interpret test data.o*net - 16402021-06-14 14:41:02.763683Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersCivil Engineering Technologists and Technicians17-3022.00Civil Engineering Technologists and TechniciansApply theory and principles of civil engineering in planning, designing, and overseeing construction and maintenance of structures and facilities under the direction of engineering staff or physical scientists.o*net - 16412021-06-14 14:41:02.910372Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectrical and Electronic Engineering Technologists and Technicians17-3023.00Electrical and Electronic Engineering Technologists and TechniciansApply electrical and electronic theory and related knowledge, usually under the direction of engineering staff, to design, build, repair, adjust, and modify electrical components, circuitry, controls, and machinery for subsequent evaluation and use by engineering staff in making engineering design decisions.o*net - 16422021-06-14 14:41:03.023374Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectro-Mechanical and Mechatronics Technologists and Technicians17-3024.00Electro-Mechanical and Mechatronics Technologists and TechniciansOperate, test, maintain, or adjust unmanned, automated, servomechanical, or electromechanical equipment. May operate unmanned submarines, aircraft, or other equipment to observe or record visual information at sites such as oil rigs, crop fields, buildings, or for similar infrastructure, deep ocean exploration, or hazardous waste removal. May assist engineers in testing and designing robotics equipment.o*net - 16432021-06-14 14:41:03.140367Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersElectro-Mechanical and Mechatronics Technologists and Technicians17-3024.01Robotics TechniciansBuild, install, test, or maintain robotic equipment or related automated production systems.o*net - 16442021-06-14 14:41:03.256374Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEnvironmental Engineering Technologists and Technicians17-3025.00Environmental Engineering Technologists and TechniciansApply theory and principles of environmental engineering to modify, test, and operate equipment and devices used in the prevention, control, and remediation of environmental problems, including waste treatment and site remediation, under the direction of engineering staff or scientists. May assist in the development of environmental remediation devices.o*net - 16452021-06-14 14:41:03.389368Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersIndustrial Engineering Technologists and Technicians17-3026.00Industrial Engineering Technologists and TechniciansApply engineering theory and principles to problems of industrial layout or manufacturing production, usually under the direction of engineering staff. May perform time and motion studies on worker operations in a variety of industries for purposes such as establishing standard production rates or improving efficiency.o*net - 16472021-06-14 14:41:03.643556Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersMechanical Engineering Technologists and Technicians17-3027.00Mechanical Engineering Technologists and TechniciansApply theory and principles of mechanical engineering to modify, develop, test, or adjust machinery and equipment under direction of engineering staff or physical scientists.o*net - 16482021-06-14 14:41:03.802557Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersMechanical Engineering Technologists and Technicians17-3027.01Automotive Engineering TechniciansAssist engineers in determining the practicality of proposed product design changes and plan and carry out tests on experimental test devices or equipment for performance, durability, or efficiency.o*net - 16502021-06-14 14:41:04.033585Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029.00Engineering Technologists and Technicians, Except Drafters, All OtherAll engineering technologists and technicians, except drafters, not listed separately.o*net - 16512021-06-14 14:41:04.147123Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029.01Non-Destructive Testing SpecialistsTest the safety of structures, vehicles, or vessels using x-ray, ultrasound, fiber optic or related equipment.o*net - 16522021-06-14 14:41:04.265321Architecture and Engineering OccupationsDrafters, Engineering Technicians, and Mapping TechniciansEngineering Technologists and Technicians, Except DraftersEngineering Technologists and Technicians, Except Drafters, All Other17-3029.08Photonics TechniciansBuild, install, test, or maintain optical or fiber optic equipment, such as lasers, lenses, or mirrors, using spectrometers, interferometers, or related equipment.o*net - 24732021-06-14 14:43:40.61316417-3023.01 - 24742021-06-14 14:43:40.69216417-3023.03 - 24752021-06-14 14:43:40.76716717-3029.02 - 24762021-06-14 14:43:40.82716317-3029.03 - 24772021-06-14 14:43:40.87915917-3029.04 - 24782021-06-14 14:43:40.94516117-3029.05 - 24792021-06-14 14:43:41.00915817-3029.06 - 24802021-06-14 14:43:41.07316017-3029.07 - 24812021-06-14 14:43:41.12816117-3029.09 - 24822021-06-14 14:43:41.17616417-3029.10 - 24832021-06-14 14:43:41.22516317-3029.11 - 24842021-06-14 14:43:41.28315917-3029.12 - 24852021-06-14 14:43:41.63876015-1223 - 24862021-06-14 14:43:42.06675815-1222 - 572021-06-14 14:35:08.022117Database and Network Administrators and Architects15-1240bls - 6592021-06-14 14:36:08.060134Computer and Mathematical OccupationsComputer OccupationsDatabase and Network Administrators and ArchitectsComputer Network Architects15-1241Computer Network Architectsbls - 24872021-06-14 14:43:43.93671015-1121.00 - 24882021-06-14 14:43:44.05670815-1122.00 - 24892021-06-14 14:43:44.15570715-1143.00 - 24902021-06-14 14:43:44.27270915-1143.01 - 24912021-06-14 14:43:44.37871015-1132.00 - 24922021-06-14 14:43:44.45923415-1133.00 - 24932021-06-14 14:43:44.55223615-1199.09 - 24942021-06-14 14:43:46.38638815-1199.02 - 6612021-06-14 14:36:08.416136Computer and Mathematical OccupationsComputer OccupationsDatabase and Network Administrators and ArchitectsDatabase Architects15-1243Database Architectsbls - 1142021-06-14 14:35:12.923534Miscellaneous Community and Social Service Specialists21-1090bls - 4762021-06-14 14:35:43.735571Counselors, Social Workers, and Other Community and Social Service Specialists21-1000bls - 5632021-06-14 14:35:50.909071Community and Social Service Occupations21-0000bls - 7712021-06-14 14:36:30.012910Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsSocial and Human Service Assistants21-1093Social and Human Service Assistantsbls - 7722021-06-14 14:36:30.178940Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity Health Workers21-1094Community Health Workersbls - 7732021-06-14 14:36:30.349907Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity and Social Service Specialists, All Other21-1099Community and Social Service Specialists, All Otherbls - 17322021-06-14 14:41:14.044331Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsSocial and Human Service Assistants21-1093.00Social and Human Service AssistantsAssist other social and human service providers in providing client services in a wide variety of fields, such as psychology, rehabilitation, or social work, including support for families. May assist clients in identifying and obtaining available benefits and social and community services. May assist social workers with developing, organizing, and conducting programs to prevent and resolve problems relevant to substance abuse, human relationships, rehabilitation, or dependent care.o*net - 17332021-06-14 14:41:14.162329Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity Health Workers21-1094.00Community Health WorkersPromote health within a community by assisting individuals to adopt healthy behaviors. Serve as an advocate for the health needs of individuals by assisting community residents in effectively communicating with healthcare providers or social service agencies. Act as liaison or advocate and implement programs that promote, maintain, and improve individual and overall community health. May deliver health-related preventive services such as blood pressure, glaucoma, and hearing screenings. May collect data to help identify community health needs.o*net - 17342021-06-14 14:41:14.269361Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsCommunity and Social Service Specialists, All Other21-1099.00Community and Social Service Specialists, All OtherAll community and social service specialists not listed separately.o*net - 1982021-06-14 14:35:20.491437First-Line Supervisors of Law Enforcement Workers33-1010bls - 4952021-06-14 14:35:45.207569Supervisors of Protective Service Workers33-1000bls - 5692021-06-14 14:35:51.342069Protective Service Occupations33-0000bls - 7692021-06-14 14:36:29.614836Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsHealth Education Specialists21-1091Health Education Specialistsbls - 17302021-06-14 14:41:13.790333Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsMiscellaneous Community and Social Service SpecialistsHealth Education Specialists21-1091.00Health Education SpecialistsProvide and manage health education programs that help individuals, families, and their communities maximize and maintain healthy lifestyles. Use data to identify community needs prior to planning, implementing, monitoring, and evaluating programs designed to encourage healthy lifestyles, policies, and environments. May link health systems, health providers, insurers, and patients to address individual and population health needs. May serve as resource to assist individuals, other health professionals, or the community, and may administer fiscal resources for health education programs.o*net - 562021-06-14 14:35:07.918235Computer Support Specialists15-1230bls - 6572021-06-14 14:36:07.710870Computer and Mathematical OccupationsComputer OccupationsComputer Support SpecialistsComputer Network Support Specialists15-1231Computer Network Support Specialistsbls - 6622021-06-14 14:36:08.741135Computer and Mathematical OccupationsComputer OccupationsDatabase and Network Administrators and ArchitectsNetwork and Computer Systems Administrators15-1244Network and Computer Systems Administratorsbls - 24952021-06-14 14:43:50.07004115-1152.00 - 24962021-06-14 14:43:50.13504515-1142.00 - 452021-06-14 14:35:06.867237Accountants and Auditors13-2010bls - 472021-06-14 14:35:07.043237Budget Analysts13-2030bls - 482021-06-14 14:35:07.139237Credit Analysts13-2040bls - 502021-06-14 14:35:07.332235Financial Examiners13-2060bls - 522021-06-14 14:35:07.559241Tax Examiners, Collectors and Preparers, and Revenue Agents13-2080bls - 4652021-06-14 14:35:42.852499Financial Specialists13-2000bls - 6392021-06-14 14:36:04.418696Business and Financial Operations OccupationsFinancial SpecialistsAccountants and AuditorsAccountants and Auditors13-2011Accountants and Auditorsbls - 6422021-06-14 14:36:04.965996Business and Financial Operations OccupationsFinancial SpecialistsBudget AnalystsBudget Analysts13-2031Budget Analystsbls - 6432021-06-14 14:36:05.123825Business and Financial Operations OccupationsFinancial SpecialistsCredit AnalystsCredit Analysts13-2041Credit Analystsbls - 6482021-06-14 14:36:06.038318Business and Financial Operations OccupationsFinancial SpecialistsFinancial ExaminersFinancial Examiners13-2061Financial Examinersbls - 6512021-06-14 14:36:06.593319Business and Financial Operations OccupationsFinancial SpecialistsTax Examiners, Collectors and Preparers, and Revenue AgentsTax Examiners and Collectors, and Revenue Agents13-2081Tax Examiners and Collectors, and Revenue Agentsbls - 15402021-06-14 14:40:49.642083Business and Financial Operations OccupationsFinancial SpecialistsAccountants and AuditorsAccountants and Auditors13-2011.00Accountants and AuditorsExamine, analyze, and interpret accounting records to prepare financial statements, give advice, or audit and evaluate statements prepared by others. Install or advise on systems of recording costs or other financial and budgetary data.o*net - 15432021-06-14 14:40:50.038068Business and Financial Operations OccupationsFinancial SpecialistsBudget AnalystsBudget Analysts13-2031.00Budget AnalystsExamine budget estimates for completeness, accuracy, and conformance with procedures and regulations. Analyze budgeting and accounting reports.o*net - 15442021-06-14 14:40:50.204070Business and Financial Operations OccupationsFinancial SpecialistsCredit AnalystsCredit Analysts13-2041.00Credit AnalystsAnalyze credit data and financial statements of individuals or firms to determine the degree of risk involved in extending credit or lending money. Prepare reports with credit information for use in decisionmaking.o*net - 15492021-06-14 14:40:50.912825Business and Financial Operations OccupationsFinancial SpecialistsFinancial ExaminersFinancial Examiners13-2061.00Financial ExaminersEnforce or ensure compliance with laws and regulations governing financial and securities institutions and financial and real estate transactions. May examine, verify, or authenticate records.o*net - 15522021-06-14 14:40:51.315833Business and Financial Operations OccupationsFinancial SpecialistsTax Examiners, Collectors and Preparers, and Revenue AgentsTax Examiners and Collectors, and Revenue Agents13-2081.00Tax Examiners and Collectors, and Revenue AgentsDetermine tax liability or collect taxes from individuals or business firms according to prescribed laws and regulations.o*net - 24972021-06-14 14:43:51.66548413-2011.01 - 492021-06-14 14:35:07.238234Financial Analysts and Advisors13-2050bls - 6442021-06-14 14:36:05.295237Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsFinancial and Investment Analysts13-2051Financial and Investment Analystsbls - 6452021-06-14 14:36:05.513316Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsPersonal Financial Advisors13-2052Personal Financial Advisorsbls - 6462021-06-14 14:36:05.705317Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsInsurance Underwriters13-2053Insurance Underwritersbls - 6472021-06-14 14:36:05.891319Business and Financial Operations OccupationsFinancial SpecialistsFinancial Analysts and AdvisorsFinancial Risk Specialists13-2054Financial Risk Specialistsbls - 6522021-06-14 14:36:06.759316Business and Financial Operations OccupationsFinancial SpecialistsTax Examiners, Collectors and Preparers, and Revenue AgentsTax Preparers13-2082Tax Preparersbls - 72021-06-14 14:35:02.925162Administrative Services and Facilities Managers11-3010bls - 92021-06-14 14:35:03.143704Financial Managers11-3030bls - 4622021-06-14 14:35:42.625493Operations Specialties Managers11-3000bls - 5582021-06-14 14:35:50.542053Management Occupations11-0000bls - 5892021-06-14 14:35:54.363446Management OccupationsOperations Specialties ManagersAdministrative Services and Facilities ManagersAdministrative Services Managers11-3012Administrative Services Managersbls - 5902021-06-14 14:35:54.628490Management OccupationsOperations Specialties ManagersAdministrative Services and Facilities ManagersFacilities Managers11-3013Facilities Managersbls - 5922021-06-14 14:35:54.983491Management OccupationsOperations Specialties ManagersFinancial ManagersFinancial Managers11-3031Financial Managersbls - 14612021-06-14 14:40:39.457947Management OccupationsOperations Specialties ManagersFinancial ManagersFinancial Managers11-3031.00Financial ManagersPlan, direct, or coordinate accounting, investing, banking, insurance, securities, and other financial activities of a branch, office, or department of an establishment.o*net - 14622021-06-14 14:40:39.614946Management OccupationsOperations Specialties ManagersFinancial ManagersFinancial Managers11-3031.01Treasurers and ControllersDirect financial activities, such as planning, procurement, and investments for all or part of an organization.o*net - 24982021-06-14 14:43:52.84128811-3031.02 - 24992021-06-14 14:43:52.89028311-3011.00 - 6292021-06-14 14:36:02.251291Business and Financial Operations OccupationsBusiness Operations SpecialistsHuman Resources WorkersLabor Relations Specialists13-1075Labor Relations Specialistsbls - 12021-06-14 14:35:01.990157Chief Executives11-1010bls - 22021-06-14 14:35:02.204159General and Operations Managers11-1020bls - 42021-06-14 14:35:02.418159Advertising and Promotions Managers11-2010bls - 52021-06-14 14:35:02.654158Marketing and Sales Managers11-2020bls - 102021-06-14 14:35:03.233706Industrial Production Managers11-3050bls - 122021-06-14 14:35:03.440732Transportation, Storage, and Distribution Managers11-3070bls - 172021-06-14 14:35:03.912233Construction Managers11-9020bls - 272021-06-14 14:35:05.044822Social and Community Service Managers11-9150bls - 302021-06-14 14:35:05.343824Miscellaneous Managers11-9190bls - 352021-06-14 14:35:05.845819Cost Estimators13-1050bls - 2232021-06-14 14:35:22.498191First-Line Supervisors of Building and Grounds Cleaning and Maintenance Workers37-1010bls - 2272021-06-14 14:35:22.826184First-Line Supervisors of Entertainment and Recreation Workers39-1010bls - 2282021-06-14 14:35:22.898186First-Line Supervisors of Personal Service Workers39-1020bls - 4602021-06-14 14:35:42.438499Top Executives11-1000bls - 4612021-06-14 14:35:42.537495Advertising, Marketing, Promotions, Public Relations, and Sales Managers11-2000bls - 4632021-06-14 14:35:42.707494Other Management Occupations11-9000bls - 5032021-06-14 14:35:45.877570Supervisors of Building and Grounds Cleaning and Maintenance Workers37-1000bls - 5062021-06-14 14:35:46.075571Supervisors of Personal Care and Service Workers39-1000bls - 5712021-06-14 14:35:51.603070Building and Grounds Cleaning and Maintenance Occupations37-0000bls - 5722021-06-14 14:35:51.686075Personal Care and Service Occupations39-0000bls - 5812021-06-14 14:35:52.710074Management OccupationsTop ExecutivesChief ExecutivesChief Executives11-1011Chief Executivesbls - 5822021-06-14 14:35:52.927073Management OccupationsTop ExecutivesGeneral and Operations ManagersGeneral and Operations Managers11-1021General and Operations Managersbls - 5932021-06-14 14:35:55.170489Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051Industrial Production Managersbls - 5952021-06-14 14:35:55.536080Management OccupationsOperations Specialties ManagersTransportation, Storage, and Distribution ManagersTransportation, Storage, and Distribution Managers11-3071Transportation, Storage, and Distribution Managersbls - 6002021-06-14 14:35:56.404622Management OccupationsOther Management OccupationsConstruction ManagersConstruction Managers11-9021Construction Managersbls - 6142021-06-14 14:35:59.331417Management OccupationsOther Management OccupationsSocial and Community Service ManagersSocial and Community Service Managers11-9151Social and Community Service Managersbls - 6182021-06-14 14:36:00.067410Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199Managers, All Otherbls - 6262021-06-14 14:36:01.677933Business and Financial Operations OccupationsBusiness Operations SpecialistsCost EstimatorsCost Estimators13-1051Cost Estimatorsbls - 10242021-06-14 14:37:26.947314Building and Grounds Cleaning and Maintenance OccupationsSupervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Housekeeping and Janitorial Workers37-1011First-Line Supervisors of Housekeeping and Janitorial Workersbls - 10362021-06-14 14:37:28.865937Personal Care and Service OccupationsSupervisors of Personal Care and Service WorkersFirst-Line Supervisors of Personal Service WorkersFirst-Line Supervisors of Personal Service Workers39-1022First-Line Supervisors of Personal Service Workersbls - 14482021-06-14 14:40:37.016423Management OccupationsTop ExecutivesChief ExecutivesChief Executives11-1011.00Chief ExecutivesDetermine and formulate policies and provide overall direction of companies or private and public sector organizations within guidelines set up by a board of directors or similar governing body. Plan, direct, or coordinate operational activities at the highest level of management with the help of subordinate executives and staff managers.o*net - 14502021-06-14 14:40:37.598961Management OccupationsTop ExecutivesGeneral and Operations ManagersGeneral and Operations Managers11-1021.00General and Operations ManagersPlan, direct, or coordinate the operations of public or private sector organizations, overseeing multiple departments or locations. Duties and responsibilities include formulating policies, managing daily operations, and planning the use of materials and human resources, but are too diverse and general in nature to be classified in any one functional area of management or administration, such as personnel, purchasing, or administrative services. Usually manage through subordinate supervisors. Excludes First-Line Supervisors.o*net - 14522021-06-14 14:40:37.912963Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersAdvertising and Promotions ManagersAdvertising and Promotions Managers11-2011.00Advertising and Promotions ManagersPlan, direct, or coordinate advertising policies and programs or produce collateral materials, such as posters, contests, coupons, or giveaways, to create extra interest in the purchase of a product or service for a department, an entire organization, or on an account basis.o*net - 14532021-06-14 14:40:38.063017Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersMarketing Managers11-2021.00Marketing ManagersPlan, direct, or coordinate marketing policies and programs, such as determining the demand for products and services offered by a firm and its competitors, and identify potential customers. Develop pricing strategies with the goal of maximizing the firm's profits or share of the market while ensuring the firm's customers are satisfied. Oversee product development or monitor trends that indicate the need for new products and services.o*net - 14542021-06-14 14:40:38.225940Management OccupationsAdvertising, Marketing, Promotions, Public Relations, and Sales ManagersMarketing and Sales ManagersSales Managers11-2022.00Sales ManagersPlan, direct, or coordinate the actual distribution or movement of a product or service to the customer. Coordinate sales distribution by establishing sales territories, quotas, and goals and establish training programs for sales representatives. Analyze sales statistics gathered by staff to determine sales potential and inventory requirements and monitor the preferences of customers.o*net - 14572021-06-14 14:40:38.739941Management OccupationsOperations Specialties ManagersAdministrative Services and Facilities ManagersAdministrative Services Managers11-3012.00Administrative Services ManagersPlan, direct, or coordinate one or more administrative services of an organization, such as records and information management, mail distribution, and other office support services.o*net - 14642021-06-14 14:40:39.923972Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.00Industrial Production ManagersPlan, direct, or coordinate the work activities and resources necessary for manufacturing products in accordance with cost, quality, and quantity specifications.o*net - 14712021-06-14 14:40:40.839886Management OccupationsOperations Specialties ManagersTransportation, Storage, and Distribution ManagersTransportation, Storage, and Distribution Managers11-3071.00Transportation, Storage, and Distribution ManagersPlan, direct, or coordinate transportation, storage, or distribution activities in accordance with organizational policies and applicable government laws or regulations. Includes logistics managers.o*net - 14772021-06-14 14:40:41.695748Management OccupationsOther Management OccupationsConstruction ManagersConstruction Managers11-9021.00Construction ManagersPlan, direct, or coordinate, usually through subordinate supervisory personnel, activities concerned with the construction and maintenance of structures, facilities, and systems. Participate in the conceptual development of a construction project and oversee its organization, scheduling, budgeting, and implementation. Includes managers in specialized construction fields, such as carpentry or plumbing.o*net - 14942021-06-14 14:40:43.978215Management OccupationsOther Management OccupationsSocial and Community Service ManagersSocial and Community Service Managers11-9151.00Social and Community Service ManagersPlan, direct, or coordinate the activities of a social service program or community outreach organization. Oversee the program or organization's budget and policies regarding participant involvement, program requirements, and benefits. Work may involve directing social workers, counselors, or probation officers.o*net - 15002021-06-14 14:40:44.813290Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.00Managers, All OtherAll managers not listed separately.o*net - 15202021-06-14 14:40:47.239188Business and Financial Operations OccupationsBusiness Operations SpecialistsCost EstimatorsCost Estimators13-1051.00Cost EstimatorsPrepare cost estimates for product manufacturing, construction projects, or services to aid management in bidding on or determining price of product or service. May specialize according to particular service performed or type of product manufactured.o*net - 15282021-06-14 14:40:48.196409Business and Financial Operations OccupationsBusiness Operations SpecialistsManagement AnalystsManagement Analysts13-1111.00Management AnalystsConduct organizational studies and evaluations, design systems and procedures, conduct work simplification and measurement studies, and prepare operations and procedures manuals to assist management in operating more efficiently and effectively. Includes program analysts and management consultants.o*net - 15332021-06-14 14:40:48.802524Business and Financial Operations OccupationsBusiness Operations SpecialistsMarket Research Analysts and Marketing SpecialistsMarket Research Analysts and Marketing Specialists13-1161.00Market Research Analysts and Marketing SpecialistsResearch conditions in local, regional, national, or online markets. Gather information to determine potential sales of a product or service, or plan a marketing or advertising campaign. May gather information on competitors, prices, sales, and methods of marketing and distribution. May employ search marketing tactics, analyze web metrics, and develop recommendations to increase search engine ranking and visibility to target markets.o*net - 20212021-06-14 14:41:47.909544Building and Grounds Cleaning and Maintenance OccupationsSupervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Building and Grounds Cleaning and Maintenance WorkersFirst-Line Supervisors of Housekeeping and Janitorial Workers37-1011.00First-Line Supervisors of Housekeeping and Janitorial WorkersDirectly supervise and coordinate work activities of cleaning personnel in hotels, hospitals, offices, and other establishments.o*net - 20332021-06-14 14:41:49.217526Personal Care and Service OccupationsSupervisors of Personal Care and Service WorkersFirst-Line Supervisors of Personal Service WorkersFirst-Line Supervisors of Personal Service Workers39-1022.00First-Line Supervisors of Personal Service WorkersSupervise and coordinate activities of personal service workers.o*net - 25002021-06-14 14:43:55.98697339-1011 - 25012021-06-14 14:43:56.07097539-1011.00 - 752021-06-14 14:35:09.714658Environmental Engineers17-2080bls - 762021-06-14 14:35:09.795693Industrial Engineers, Including Health and Safety17-2110bls - 6872021-06-14 14:36:13.418391Architecture and Engineering OccupationsEngineersEnvironmental EngineersEnvironmental Engineers17-2081Environmental Engineersbls - 6882021-06-14 14:36:13.602395Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyHealth and Safety Engineers, Except Mining Safety Engineers and Inspectors17-2111Health and Safety Engineers, Except Mining Safety Engineers and Inspectorsbls - 6892021-06-14 14:36:13.779782Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyIndustrial Engineers17-2112Industrial Engineersbls - 16112021-06-14 14:40:58.932364Architecture and Engineering OccupationsEngineersEnvironmental EngineersEnvironmental Engineers17-2081.00Environmental EngineersResearch, design, plan, or perform engineering duties in the prevention, control, and remediation of environmental hazards using various engineering disciplines. Work may include waste treatment, site remediation, or pollution control technology.o*net - 16122021-06-14 14:40:59.046332Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyHealth and Safety Engineers, Except Mining Safety Engineers and Inspectors17-2111.00Health and Safety Engineers, Except Mining Safety Engineers and InspectorsPromote worksite or product safety by applying knowledge of industrial processes, mechanics, chemistry, psychology, and industrial health and safety laws. Includes industrial product safety engineers.o*net - 16132021-06-14 14:40:59.177095Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyHealth and Safety Engineers, Except Mining Safety Engineers and Inspectors17-2111.02Fire-Prevention and Protection EngineersResearch causes of fires, determine fire protection methods, and design or recommend materials or equipment such as structural components or fire-detection equipment to assist organizations in safeguarding life and property against fire, explosion, and related hazards.o*net - 16142021-06-14 14:40:59.293692Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyIndustrial Engineers17-2112.00Industrial EngineersDesign, develop, test, and evaluate integrated systems for managing industrial production processes, including human work factors, quality control, inventory control, logistics and material flow, cost analysis, and production coordination.o*net - 16152021-06-14 14:40:59.405691Architecture and Engineering OccupationsEngineersIndustrial Engineers, Including Health and SafetyIndustrial Engineers17-2112.01Human Factors Engineers and ErgonomistsDesign objects, facilities, and environments to optimize human well-being and overall system performance, applying theory, principles, and data regarding the relationship between humans and respective technology. Investigate and analyze characteristics of human behavior and performance as it relates to the use of technology.o*net - 25022021-06-14 14:43:57.84826017-2081.01 - 25032021-06-14 14:43:57.89983417-2111.01 - 25042021-06-14 14:43:57.95580017-2111.03 - 18062021-06-14 14:41:22.692011Educational Instruction and Library OccupationsLibrarians, Curators, and ArchivistsLibrary TechniciansLibrary Technicians25-4031.00Library TechniciansAssist librarians by helping readers in the use of library catalogs, databases, and indexes to locate books and other materials; and by answering questions that require only brief consultation of standard reference. Compile records; sort and shelve books or other media; remove or repair damaged books or other media; register patrons; and check materials in and out of the circulation process. Replace materials in shelving area (stacks) or files. Includes bookmobile drivers who assist with providing services in mobile libraries.o*net - 25052021-06-14 14:43:59.72127825-4021.00 - 1122021-06-14 14:35:12.758535Counselors21-1010bls - 1132021-06-14 14:35:12.837531Social Workers21-1020bls - 1682021-06-14 14:35:17.815821Optometrists29-1040bls - 1772021-06-14 14:35:18.548440Nurse Practitioners29-1170bls - 7592021-06-14 14:36:27.766207Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsSubstance Abuse and Behavioral Disorder Counselors21-1011Substance Abuse and Behavioral Disorder Counselorsbls - 7622021-06-14 14:36:28.298017Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsMental Health Counselors21-1014Mental Health Counselorsbls - 7662021-06-14 14:36:29.050838Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsSocial WorkersHealthcare Social Workers21-1022Healthcare Social Workersbls - 9002021-06-14 14:36:55.262783Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersOptometristsOptometrists29-1041Optometristsbls - 9162021-06-14 14:36:57.936515Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersNurse PractitionersNurse Practitioners29-1171Nurse Practitionersbls - 17202021-06-14 14:41:12.617778Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsSubstance Abuse and Behavioral Disorder Counselors21-1011.00Substance Abuse and Behavioral Disorder CounselorsCounsel and advise individuals with alcohol, tobacco, drug, or other problems, such as gambling and eating disorders. May counsel individuals, families, or groups or engage in prevention programs.o*net - 17232021-06-14 14:41:13.027799Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsCounselorsMental Health Counselors21-1014.00Mental Health CounselorsCounsel and advise individuals and groups to promote optimum mental and emotional health, with an emphasis on prevention. May help individuals deal with a broad range of mental health issues, such as those associated with addictions and substance abuse; family, parenting, and marital problems; stress management; self-esteem; or aging.o*net - 17272021-06-14 14:41:13.464799Community and Social Service OccupationsCounselors, Social Workers, and Other Community and Social Service SpecialistsSocial WorkersHealthcare Social Workers21-1022.00Healthcare Social WorkersProvide individuals, families, and groups with the psychosocial support needed to cope with chronic, acute, or terminal illnesses. Services include advising family caregivers. Provide patients with information and counseling, and make referrals for other services. May also provide case and care management or interventions designed to promote health, prevent disease, and address barriers to access to healthcare.o*net - 18662021-06-14 14:41:30.006598Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersOptometristsOptometrists29-1041.00OptometristsDiagnose, manage, and treat conditions and diseases of the human eye and visual system. Examine eyes and visual system, diagnose problems or impairments, prescribe corrective lenses, and provide treatment. May prescribe therapeutic drugs to treat specific eye conditions.o*net - 18902021-06-14 14:41:32.478173Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersNurse PractitionersNurse Practitioners29-1171.00Nurse PractitionersDiagnose and treat acute, episodic, or chronic illness, independently or as part of a healthcare team. May focus on health promotion and disease prevention. May order, perform, or interpret diagnostic tests such as lab work and x rays. May prescribe medication. Must be registered nurses who have specialized graduate education.o*net - 1812021-06-14 14:35:18.851438Miscellaneous Healthcare Diagnosing or Treating Practitioners29-1290bls - 9362021-06-14 14:37:02.215532Healthcare Practitioners and Technical OccupationsHealthcare Diagnosing or Treating PractitionersMiscellaneous Healthcare Diagnosing or Treating PractitionersDental Hygienists29-1292Dental Hygienistsbls - 25062021-06-14 14:44:00.61533229-2021.00 - 1972021-06-14 14:35:20.387439Miscellaneous Healthcare Support Occupations31-9090bls - 4942021-06-14 14:35:45.136575Other Healthcare Support Occupations31-9000bls - 5682021-06-14 14:35:51.271071Healthcare Support Occupations31-0000bls - 9762021-06-14 14:37:08.814104Healthcare Support OccupationsOther Healthcare Support OccupationsMiscellaneous Healthcare Support OccupationsMedical Assistants31-9092Medical Assistantsbls - 19662021-06-14 14:41:41.634872Healthcare Support OccupationsOther Healthcare Support OccupationsMiscellaneous Healthcare Support OccupationsMedical Assistants31-9092.00Medical AssistantsPerform administrative and certain clinical duties under the direction of a physician. Administrative duties may include scheduling appointments, maintaining medical records, billing, and coding information for insurance purposes. Clinical duties may include taking and recording vital signs and medical histories, preparing patients for examination, drawing blood, and administering medications as directed by physician.o*net - 322021-06-14 14:35:05.566821Buyers and Purchasing Agents13-1020bls - 632021-06-14 14:35:08.694119Statisticians15-2040bls - 972021-06-14 14:35:11.521334Economists19-3010bls - 1082021-06-14 14:35:12.369837Social Science Research Assistants19-4060bls - 2042021-06-14 14:35:21.006439Detectives and Criminal Investigators33-3020bls - 4672021-06-14 14:35:42.988496Mathematical Science Occupations15-2000bls - 4732021-06-14 14:35:43.476026Social Scientists and Related Workers19-3000bls - 4742021-06-14 14:35:43.581022Life, Physical, and Social Science Technicians19-4000bls - 4972021-06-14 14:35:45.356570Law Enforcement Workers33-3000bls - 5622021-06-14 14:35:50.842076Life, Physical, and Social Science Occupations19-0000bls - 6202021-06-14 14:36:00.446412Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsBuyers and Purchasing Agents, Farm Products13-1021Buyers and Purchasing Agents, Farm Productsbls - 6212021-06-14 14:36:00.659446Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsWholesale and Retail Buyers, Except Farm Products13-1022Wholesale and Retail Buyers, Except Farm Productsbls - 6222021-06-14 14:36:00.872414Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsPurchasing Agents, Except Wholesale, Retail, and Farm Products13-1023Purchasing Agents, Except Wholesale, Retail, and Farm Productsbls - 6722021-06-14 14:36:10.658688Computer and Mathematical OccupationsMathematical Science OccupationsStatisticiansStatisticians15-2041Statisticiansbls - 7322021-06-14 14:36:22.064780Life, Physical, and Social Science OccupationsSocial Scientists and Related WorkersEconomistsEconomists19-3011Economistsbls - 7532021-06-14 14:36:26.592098Life, Physical, and Social Science OccupationsLife, Physical, and Social Science TechniciansSocial Science Research AssistantsSocial Science Research Assistants19-4061Social Science Research Assistantsbls - 15022021-06-14 14:40:45.089290Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.02Compliance ManagersPlan, direct, or coordinate activities of an organization to ensure compliance with ethical or regulatory standards.o*net - 15082021-06-14 14:40:45.821388Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsBuyers and Purchasing Agents, Farm Products13-1021.00Buyers and Purchasing Agents, Farm ProductsPurchase farm products either for further processing or resale. Includes tree farm contractors, grain brokers and market operators, grain buyers, and tobacco buyers. May negotiate contracts.o*net - 15092021-06-14 14:40:45.941385Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsWholesale and Retail Buyers, Except Farm Products13-1022.00Wholesale and Retail Buyers, Except Farm ProductsBuy merchandise or commodities, other than farm products, for resale to consumers at the wholesale or retail level, including both durable and nondurable goods. Analyze past buying trends, sales records, price, and quality of merchandise to determine value and yield. Select, order, and authorize payment for merchandise according to contractual agreements. May conduct meetings with sales personnel and introduce new products. May negotiate contracts. Includes assistant wholesale and retail buyers of nonfarm products.o*net - 15102021-06-14 14:40:46.053383Business and Financial Operations OccupationsBusiness Operations SpecialistsBuyers and Purchasing AgentsPurchasing Agents, Except Wholesale, Retail, and Farm Products13-1023.00Purchasing Agents, Except Wholesale, Retail, and Farm ProductsPurchase machinery, equipment, tools, parts, supplies, or services necessary for the operation of an establishment. Purchase raw or semifinished materials for manufacturing. May negotiate contracts.o*net - 15882021-06-14 14:40:56.123269Computer and Mathematical OccupationsMathematical Science OccupationsStatisticiansStatisticians15-2041.00StatisticiansDevelop or apply mathematical or statistical theory and methods to collect, organize, interpret, and summarize numerical data to provide usable information. May specialize in fields such as biostatistics, agricultural statistics, business statistics, or economic statistics. Includes mathematical and survey statisticians.o*net - 16852021-06-14 14:41:08.473329Life, Physical, and Social Science OccupationsSocial Scientists and Related WorkersEconomistsEconomists19-3011.00EconomistsConduct research, prepare reports, or formulate plans to address economic problems related to the production and distribution of goods and services or monetary and fiscal policy. May collect and process economic and statistical data using sampling techniques and econometric methods.o*net - 17122021-06-14 14:41:11.523130Life, Physical, and Social Science OccupationsLife, Physical, and Social Science TechniciansSocial Science Research AssistantsSocial Science Research Assistants19-4061.00Social Science Research AssistantsAssist social scientists in laboratory, survey, and other social science research. May help prepare findings for publication and assist in laboratory analysis, quality control, or data management.o*net - 25072021-06-14 14:44:01.73575013-2011.02 - 372021-06-14 14:35:06.035826Logisticians and Project Management Specialists13-1080bls - 412021-06-14 14:35:06.479825Compensation, Benefits, and Job Analysis Specialists13-1140bls - 422021-06-14 14:35:06.590824Training and Development Specialists13-1150bls - 442021-06-14 14:35:06.771825Miscellaneous Business Operations Specialists13-1190bls - 6302021-06-14 14:36:02.433134Business and Financial Operations OccupationsBusiness Operations SpecialistsLogisticians and Project Management SpecialistsLogisticians13-1081Logisticiansbls - 6312021-06-14 14:36:02.643140Business and Financial Operations OccupationsBusiness Operations SpecialistsLogisticians and Project Management SpecialistsProject Management Specialists13-1082Project Management Specialistsbls - 6352021-06-14 14:36:03.703134Business and Financial Operations OccupationsBusiness Operations SpecialistsCompensation, Benefits, and Job Analysis SpecialistsCompensation, Benefits, and Job Analysis Specialists13-1141Compensation, Benefits, and Job Analysis Specialistsbls - 6362021-06-14 14:36:03.876134Business and Financial Operations OccupationsBusiness Operations SpecialistsTraining and Development SpecialistsTraining and Development Specialists13-1151Training and Development Specialistsbls - 25082021-06-14 14:44:02.63944113-1191 - 622021-06-14 14:35:08.608117Operations Research Analysts15-2030bls - 6712021-06-14 14:36:10.458686Computer and Mathematical OccupationsMathematical Science OccupationsOperations Research AnalystsOperations Research Analysts15-2031Operations Research Analystsbls - 15872021-06-14 14:40:55.994729Computer and Mathematical OccupationsMathematical Science OccupationsOperations Research AnalystsOperations Research Analysts15-2031.00Operations Research AnalystsFormulate and apply mathematical modeling and other optimizing methods to develop and interpret information that assists management with decisionmaking, policy formulation, or other managerial functions. May collect and analyze data and develop decision support software, services, or products. May develop and supply optimal time, cost, or logistics networks for program evaluation, review, or implementation.o*net - 82021-06-14 14:35:03.040165Computer and Information Systems Managers11-3020bls - 112021-06-14 14:35:03.322699Purchasing Managers11-3060bls - 132021-06-14 14:35:03.535729Compensation and Benefits Managers11-3110bls - 232021-06-14 14:35:04.557822Medical and Health Services Managers11-9110bls - 5912021-06-14 14:35:54.806497Management OccupationsOperations Specialties ManagersComputer and Information Systems ManagersComputer and Information Systems Managers11-3021Computer and Information Systems Managersbls - 5942021-06-14 14:35:55.329083Management OccupationsOperations Specialties ManagersPurchasing ManagersPurchasing Managers11-3061Purchasing Managersbls - 5962021-06-14 14:35:55.716082Management OccupationsOperations Specialties ManagersCompensation and Benefits ManagersCompensation and Benefits Managers11-3111Compensation and Benefits Managersbls - 6102021-06-14 14:35:58.473812Management OccupationsOther Management OccupationsMedical and Health Services ManagersMedical and Health Services Managers11-9111Medical and Health Services Managersbls - 14492021-06-14 14:40:37.350957Management OccupationsTop ExecutivesChief ExecutivesChief Executives11-1011.03Chief Sustainability OfficersCommunicate and coordinate with management, shareholders, customers, and employees to address sustainability issues. Enact or oversee a corporate sustainability strategy.o*net - 14602021-06-14 14:40:39.270941Management OccupationsOperations Specialties ManagersComputer and Information Systems ManagersComputer and Information Systems Managers11-3021.00Computer and Information Systems ManagersPlan, direct, or coordinate activities in such fields as electronic data processing, information systems, systems analysis, and computer programming.o*net - 14652021-06-14 14:40:40.047942Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.01Quality Control Systems ManagersPlan, direct, or coordinate quality assurance programs. Formulate quality control policies and control quality of laboratory and production efforts.o*net - 14662021-06-14 14:40:40.185978Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.02Geothermal Production ManagersManage operations at geothermal power generation facilities. Maintain and monitor geothermal plant equipment for efficient and safe plant operations.o*net - 14672021-06-14 14:40:40.324980Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.03Biofuels Production ManagersManage biofuels production and plant operations. Collect and process information on plant production and performance, diagnose problems, and design corrective procedures.o*net - 14682021-06-14 14:40:40.469974Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.04Biomass Power Plant ManagersManage operations at biomass power generation facilities. Direct work activities at plant, including supervision of operations and maintenance staff.o*net - 14692021-06-14 14:40:40.580979Management OccupationsOperations Specialties ManagersIndustrial Production ManagersIndustrial Production Managers11-3051.06Hydroelectric Production ManagersManage operations at hydroelectric power generation facilities. Maintain and monitor hydroelectric plant equipment for efficient and safe plant operations.o*net - 14702021-06-14 14:40:40.709971Management OccupationsOperations Specialties ManagersPurchasing ManagersPurchasing Managers11-3061.00Purchasing ManagersPlan, direct, or coordinate the activities of buyers, purchasing officers, and related workers involved in purchasing materials, products, and services. Includes wholesale or retail trade merchandising managers and procurement managers.o*net - 14732021-06-14 14:40:41.097886Management OccupationsOperations Specialties ManagersCompensation and Benefits ManagersCompensation and Benefits Managers11-3111.00Compensation and Benefits ManagersPlan, direct, or coordinate compensation and benefits activities of an organization.o*net - 14882021-06-14 14:40:43.219560Management OccupationsOther Management OccupationsMedical and Health Services ManagersMedical and Health Services Managers11-9111.00Medical and Health Services ManagersPlan, direct, or coordinate medical and health services in hospitals, clinics, managed care organizations, public health agencies, or similar organizations.o*net - 15012021-06-14 14:40:44.948290Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.01Regulatory Affairs ManagersPlan, direct, or coordinate production activities of an organization to ensure compliance with regulations and standard operating procedures.o*net - 15032021-06-14 14:40:45.212350Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.08Loss Prevention ManagersPlan and direct policies, procedures, or systems to prevent the loss of assets. Determine risk exposure or potential liability, and develop risk control measures.o*net - 15042021-06-14 14:40:45.343419Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.09Wind Energy Operations ManagersManage wind field operations, including personnel, maintenance activities, financial activities, and planning.o*net - 15052021-06-14 14:40:45.467384Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.10Wind Energy Development ManagersLead or manage the development and evaluation of potential wind energy business opportunities, including environmental studies, permitting, and proposals. May also manage construction of projects.o*net - 15062021-06-14 14:40:45.578389Management OccupationsOther Management OccupationsMiscellaneous ManagersManagers, All Other11-9199.11Brownfield Redevelopment Specialists and Site ManagersPlan and direct cleanup and redevelopment of contaminated properties for reuse. Does not include properties sufficiently contaminated to qualify as Superfund sites.o*net - 25092021-06-14 14:44:03.79464011-3051.05 - 25102021-06-14 14:44:03.85364811-3071.01 - 25112021-06-14 14:44:03.89661811-3071.02 - 25122021-06-14 14:44:03.93961411-3071.03 - 25132021-06-14 14:44:03.99163711-9199.03 - 25142021-06-14 14:44:04.04161511-9199.04 - 25152021-06-14 14:44:04.08564511-9199.07 - 142021-06-14 14:35:03.638264Human Resources Managers11-3120bls - 152021-06-14 14:35:03.736177Training and Development Managers11-3130bls - 5972021-06-14 14:35:55.877109Management OccupationsOperations Specialties ManagersHuman Resources ManagersHuman Resources Managers11-3121Human Resources Managersbls - 5982021-06-14 14:35:56.044078Management OccupationsOperations Specialties ManagersTraining and Development ManagersTraining and Development Managers11-3131Training and Development Managersbls - 14742021-06-14 14:40:41.211889Management OccupationsOperations Specialties ManagersHuman Resources ManagersHuman Resources Managers11-3121.00Human Resources ManagersPlan, direct, or coordinate human resources activities and staff of an organization.o*net - 14752021-06-14 14:40:41.373746Management OccupationsOperations Specialties ManagersTraining and Development ManagersTraining and Development Managers11-3131.00Training and Development ManagersPlan, direct, or coordinate the training and development activities and staff of an organization.o*net - 1872021-06-14 14:35:19.503443Medical Records Specialists29-2070bls - 1882021-06-14 14:35:19.617443Opticians, Dispensing29-2080bls - 4902021-06-14 14:35:44.851571Health Technologists and Technicians29-2000bls - 9552021-06-14 14:37:05.583679Healthcare Practitioners and Technical OccupationsHealth Technologists and TechniciansMedical Records SpecialistsMedical Records Specialists29-2072Medical Records Specialistsbls - 9562021-06-14 14:37:05.727699Healthcare Practitioners and Technical OccupationsHealth Technologists and TechniciansOpticians, DispensingOpticians, Dispensing29-2081Opticians, Dispensingbls - 19422021-06-14 14:41:38.860920Healthcare Practitioners and Technical OccupationsHealth Technologists and TechniciansOpticians, DispensingOpticians, Dispensing29-2081.00Opticians, DispensingDesign, measure, fit, and adapt lenses and frames for client according to written optical prescription or specification. Assist client with inserting, removing, and caring for contact lenses. Assist client with selecting frames. Measure customer for size of eyeglasses and coordinate frames with facial and eye measurements and optical prescription. Prepare work order for optical laboratory containing instructions for grinding and mounting lenses in frames. Verify exactness of finished lens spectacles. Adjust frame and lens position to fit client. May shape or reshape frames. Includes contact lens opticians.o*net - 25162021-06-14 14:44:11.42995129-2071.00 - - - 12021-06-14 14:43:13.3675232021-06-14 14:43:13.367523Category.NET Framework - 22021-06-14 14:43:13.6485222021-06-14 14:43:13.648522Keyword.NET Framework - 32021-06-14 14:43:13.7565232021-06-14 14:43:13.756523KeywordADO.NET - 42021-06-14 14:43:13.8495342021-06-14 14:43:13.849534KeywordLanguage Integrated Query (LINQ) - 52021-06-14 14:43:13.9425252021-06-14 14:43:13.942525KeywordWCF Data Services - 62021-06-14 14:43:14.0225262021-06-14 14:43:14.022526KeywordXML - 72021-06-14 14:43:14.1525222021-06-14 14:43:14.152522Alignment.NET Framework2021-06-14 14:43:14.152522 - 82021-06-14 14:43:14.2415212021-06-14 14:43:14.241521AuthorWestern Governors University - 92021-06-14 14:43:14.6805212021-06-14 14:43:14.680521KeywordWindows Communication Foundation (WCF) - 102021-06-14 14:43:15.0785242021-06-14 14:43:15.078524KeywordASP.NET - 112021-06-14 14:43:15.5400272021-06-14 14:43:15.540027KeywordWindows Presentation Foundation (WPF) or Windows Forms - 122021-06-14 14:43:15.8027762021-06-14 14:43:15.802776Category3D Modeling - 132021-06-14 14:43:15.8717762021-06-14 14:43:15.871776Keyword3D Modeling - 142021-06-14 14:43:15.9279492021-06-14 14:43:15.927949KeywordDesignCAD - 152021-06-14 14:43:15.9809432021-06-14 14:43:15.980943KeywordAutodesk 3D Studio Design - 162021-06-14 14:43:16.0329482021-06-14 14:43:16.032948Keyword3ds MAX - 172021-06-14 14:43:16.0839472021-06-14 14:43:16.083947KeywordBlender - 182021-06-14 14:43:16.1289482021-06-14 14:43:16.128948KeywordLightWave - 192021-06-14 14:43:16.3962812021-06-14 14:43:16.396281Alignment3D Modeling2021-06-14 14:43:16.396281 - 202021-06-14 14:43:17.1353722021-06-14 14:43:17.135372CategoryAbstract Data Types - 212021-06-14 14:43:17.1958562021-06-14 14:43:17.195856KeywordAbstract Data Types - 222021-06-14 14:43:17.2488512021-06-14 14:43:17.248851AlignmentAbstract Data Types2021-06-14 14:43:17.248851 - 232021-06-14 14:43:17.4140492021-06-14 14:43:17.414049CategoryAcademic Accommodation Plans - 242021-06-14 14:43:17.4700492021-06-14 14:43:17.470049KeywordAcademic Accommodation Plans - 252021-06-14 14:43:17.5320522021-06-14 14:43:17.532052KeywordAccommodations - 262021-06-14 14:43:17.5820532021-06-14 14:43:17.582053StandardATD.Pers.CE - 272021-06-14 14:43:17.6310482021-06-14 14:43:17.631048StandardATD.Prof.ID - 282021-06-14 14:43:17.6800482021-06-14 14:43:17.680048StandardATD.Prof.TA - 292021-06-14 14:43:17.7340492021-06-14 14:43:17.734049StandardATD.Prof.TDF - 302021-06-14 14:43:17.7820862021-06-14 14:43:17.782086StandardISTE.Coach.C.3a - 312021-06-14 14:43:17.8370532021-06-14 14:43:17.837053StandardISTE.Coach.CA.1a - 322021-06-14 14:43:17.8880552021-06-14 14:43:17.888055StandardISTE.Coach.CA.1c - 332021-06-14 14:43:17.9350472021-06-14 14:43:17.935047StandardISTE.Coach.CL.2c - 342021-06-14 14:43:17.9870702021-06-14 14:43:17.987070StandardISTE.Coach.LD.4c - 352021-06-14 14:43:18.0290512021-06-14 14:43:18.029051StandardISTE.Coach.PLF.5a - 362021-06-14 14:43:18.0720502021-06-14 14:43:18.072050StandardISTE.Coach.PLF.5b - 372021-06-14 14:43:18.2870502021-06-14 14:43:18.287050AlignmentAcademic Accommodation Plans2021-06-14 14:43:18.287050 - 382021-06-14 14:43:19.0360432021-06-14 14:43:19.036043StandardISTE.Coach.C.3b - 392021-06-14 14:43:19.0870362021-06-14 14:43:19.087036StandardISTE.Coach.C.3d - 402021-06-14 14:43:20.0110372021-06-14 14:43:20.011037StandardATD.Org.CBP - 412021-06-14 14:43:20.0690402021-06-14 14:43:20.069040StandardATD.Org.ODC - 422021-06-14 14:43:20.1140362021-06-14 14:43:20.114036StandardATD.Pers.CL - 432021-06-14 14:43:20.1550672021-06-14 14:43:20.155067StandardATD.Pers.PM - 442021-06-14 14:43:20.2130352021-06-14 14:43:20.213035StandardISTE.Coach.CA.1b - 452021-06-14 14:43:21.6196682021-06-14 14:43:21.619668StandardATD.Prof.LS - 462021-06-14 14:43:22.7102512021-06-14 14:43:22.710251StandardISTE.Coach.LD.4b - 472021-06-14 14:43:24.7280312021-06-14 14:43:24.728031CategoryAcademic Advising - 482021-06-14 14:43:24.7791422021-06-14 14:43:24.779142KeywordAcademic Advising - 492021-06-14 14:43:24.8220642021-06-14 14:43:24.822064KeywordAcademic Counseling - 502021-06-14 14:43:24.8970642021-06-14 14:43:24.897064AlignmentAcademic Advising2021-06-14 14:43:24.897064 - 512021-06-14 14:43:25.5979042021-06-14 14:43:25.597904StandardISTE.Coach.LD.4a - 522021-06-14 14:43:25.6439062021-06-14 14:43:25.643906StandardISTE.Coach.LD.4d - 532021-06-14 14:43:26.8718152021-06-14 14:43:26.871815StandardISTE.Coach.DCA.7a - 542021-06-14 14:43:26.9108232021-06-14 14:43:26.910823StandardISTE.Coach.DCA.7b - 552021-06-14 14:43:26.9537962021-06-14 14:43:26.953796StandardISTE.Coach.DCA.7c - 562021-06-14 14:43:27.0008232021-06-14 14:43:27.000823StandardISTE.Coach.DCA.7d - 572021-06-14 14:43:29.6223382021-06-14 14:43:29.622338CategoryAcademic Tenacity - 582021-06-14 14:43:29.6963392021-06-14 14:43:29.696339KeywordAcademic Tenacity - 592021-06-14 14:43:29.7403382021-06-14 14:43:29.740338KeywordAcademic Achievement - 602021-06-14 14:43:29.7843392021-06-14 14:43:29.784339KeywordAcademic Standards - 612021-06-14 14:43:29.8398692021-06-14 14:43:29.838861KeywordAcademic Integrity - 622021-06-14 14:43:29.8968942021-06-14 14:43:29.896894KeywordPersistence - 632021-06-14 14:43:29.9498622021-06-14 14:43:29.949862StandardATD.Org.FR - 642021-06-14 14:43:29.9988642021-06-14 14:43:29.998864StandardATD.Pers.LL - 652021-06-14 14:43:30.0618632021-06-14 14:43:30.061863StandardISTE.Coach.CL.2a - 662021-06-14 14:43:30.1238642021-06-14 14:43:30.123864StandardISTE.Coach.CL.2b - 672021-06-14 14:43:30.1918692021-06-14 14:43:30.191869StandardISTE.Coach.DDM.6c - 682021-06-14 14:43:30.2698632021-06-14 14:43:30.269863StandardISTE.Coach.PLF.5c - 692021-06-14 14:43:30.3468652021-06-14 14:43:30.346865StandardCEC_2.2 - 702021-06-14 14:43:30.4158632021-06-14 14:43:30.415863StandardCEC_4.1 - 712021-06-14 14:43:30.4678612021-06-14 14:43:30.467861StandardCEC_6.2 - 722021-06-14 14:43:30.5488632021-06-14 14:43:30.548863StandardCEC_6.3 - 732021-06-14 14:43:30.6188672021-06-14 14:43:30.618867StandardUETS_5 - 742021-06-14 14:43:31.2513042021-06-14 14:43:31.251304KeywordSEL: Executive Function - 752021-06-14 14:43:31.3093752021-06-14 14:43:31.309375KeywordBeing - 762021-06-14 14:43:32.2025522021-06-14 14:43:32.202552StandardISTE.Coach.DDM.6a - 772021-06-14 14:43:32.2545592021-06-14 14:43:32.254559StandardISTE.Coach.DDM.6b - 782021-06-14 14:43:32.6858052021-06-14 14:43:32.685805KeywordThinking - 792021-06-14 14:43:33.1188072021-06-14 14:43:33.118807StandardATD.Pers.CA - 802021-06-14 14:43:35.4991882021-06-14 14:43:35.499188StandardCASEL - 812021-06-14 14:43:36.4211872021-06-14 14:43:36.421187CategoryAcademic Writing - 822021-06-14 14:43:36.4592182021-06-14 14:43:36.459218KeywordAcademic Writing - 832021-06-14 14:43:36.5212072021-06-14 14:43:36.521207AlignmentAcademic Writing2021-06-14 14:43:36.521207 - 842021-06-14 14:43:36.7020852021-06-14 14:43:36.702085KeywordAPA/MLA Style Guides - 852021-06-14 14:43:36.7491052021-06-14 14:43:36.749105StandardCEC_5.3 - 862021-06-14 14:43:36.8011002021-06-14 14:43:36.801100StandardUETS_7 - 872021-06-14 14:43:38.6728992021-06-14 14:43:38.672899CategoryAcceptance - 882021-06-14 14:43:38.7178922021-06-14 14:43:38.717892KeywordAcceptance - 892021-06-14 14:43:39.4689442021-06-14 14:43:39.468944CategoryAcceptance Testing - 902021-06-14 14:43:39.5319472021-06-14 14:43:39.531947KeywordAcceptance Testing - 912021-06-14 14:43:39.5769442021-06-14 14:43:39.576944KeywordMicrosoft Excel - 922021-06-14 14:43:39.6329422021-06-14 14:43:39.632942AlignmentAcceptance Testing2021-06-14 14:43:39.632942 - 932021-06-14 14:43:40.0671612021-06-14 14:43:40.067161KeywordCalipers - 942021-06-14 14:43:40.1141922021-06-14 14:43:40.114192KeywordCoordinate measuring machines (CMM) - 952021-06-14 14:43:40.1611602021-06-14 14:43:40.161160Keywordmicrometers - 962021-06-14 14:43:40.2011582021-06-14 14:43:40.201158Keywordrulers - 972021-06-14 14:43:40.2451952021-06-14 14:43:40.245195Keywordgauges - 982021-06-14 14:43:40.2911592021-06-14 14:43:40.291159KeywordStatistical process control (SPC) data collection devices - 992021-06-14 14:43:40.3471602021-06-14 14:43:40.347160KeywordDesign of experiments (DOE) software - 1002021-06-14 14:43:40.3951632021-06-14 14:43:40.395163KeywordMinitab - 1012021-06-14 14:43:40.4371612021-06-14 14:43:40.437161KeywordMATLAB - 1022021-06-14 14:43:40.4761902021-06-14 14:43:40.476190KeywordTolerance analysis software - 1032021-06-14 14:43:40.5251642021-06-14 14:43:40.525164KeywordAutoCAD - 1042021-06-14 14:43:42.2740182021-06-14 14:43:42.274018KeywordIBM Rational RequisitePro - 1052021-06-14 14:43:42.3287562021-06-14 14:43:42.328756KeywordUnified modeling language UML - 1062021-06-14 14:43:43.7697082021-06-14 14:43:43.769708KeywordData Variation - 1072021-06-14 14:43:44.9552352021-06-14 14:43:44.955235CertificationComp_TIA_Project_+ - 1082021-06-14 14:43:45.5728482021-06-14 14:43:45.572848KeywordScripting - 1092021-06-14 14:43:45.9143842021-06-14 14:43:45.914384KeywordWorkshop - 1102021-06-14 14:43:46.2073832021-06-14 14:43:46.207383KeywordUser Experience - 1112021-06-14 14:43:46.2783862021-06-14 14:43:46.278386CertificationAxelos_ITIL_1_Foundation - 1122021-06-14 14:43:46.7413862021-06-14 14:43:46.741386KeywordData Architecture - 1132021-06-14 14:43:47.3213882021-06-14 14:43:47.321388CategoryAccess Controls - 1142021-06-14 14:43:47.4023872021-06-14 14:43:47.402387KeywordAccess Controls - 1152021-06-14 14:43:47.4853862021-06-14 14:43:47.485386AlignmentAccess Controls2021-06-14 14:43:47.485386 - 1162021-06-14 14:43:47.7709582021-06-14 14:43:47.770958KeywordNetSupport School - 1172021-06-14 14:43:47.8219302021-06-14 14:43:47.821930KeywordLockDown Browser - 1182021-06-14 14:43:49.8600422021-06-14 14:43:49.860042CategoryAccess Network - 1192021-06-14 14:43:49.9020372021-06-14 14:43:49.902037KeywordAccess Network - 1202021-06-14 14:43:49.9510392021-06-14 14:43:49.951039KeywordMonitor - 1212021-06-14 14:43:50.0040702021-06-14 14:43:50.004070KeywordPerformance - 1222021-06-14 14:43:50.1880392021-06-14 14:43:50.188039AlignmentAccess Network2021-06-14 14:43:50.188039 - 1232021-06-14 14:43:50.3900392021-06-14 14:43:50.390039KeywordRouters - 1242021-06-14 14:43:50.4330412021-06-14 14:43:50.433041Certification350-201_CBRCOR - 1252021-06-14 14:43:50.6660422021-06-14 14:43:50.666042Certification300-410_ENARSI - 1262021-06-14 14:43:50.8690412021-06-14 14:43:50.869041Certification350-401_ENCOR - 1272021-06-14 14:43:51.0954302021-06-14 14:43:51.095430KeywordDesign - 1282021-06-14 14:43:51.1434102021-06-14 14:43:51.143410Certification300-420_ENSLD - 1292021-06-14 14:43:51.3194592021-06-14 14:43:51.319459CategoryAccount Analysis - 1302021-06-14 14:43:51.3804542021-06-14 14:43:51.380454KeywordAccount Analysis - 1312021-06-14 14:43:51.4204842021-06-14 14:43:51.420484KeywordAccount Reconciliation - 1322021-06-14 14:43:51.4594832021-06-14 14:43:51.459483CertificationCPA - 1332021-06-14 14:43:51.5064552021-06-14 14:43:51.506455CertificationCMA - 1342021-06-14 14:43:51.5524832021-06-14 14:43:51.552483CertificationCIA - 1352021-06-14 14:43:51.5934842021-06-14 14:43:51.593484CertificationCFE - 1362021-06-14 14:43:51.7144722021-06-14 14:43:51.714472AlignmentAccount Analysis2021-06-14 14:43:51.714472 - 1372021-06-14 14:43:51.9174552021-06-14 14:43:51.917455KeywordMicrosoft office Suite - 1382021-06-14 14:43:51.9624502021-06-14 14:43:51.962450KeywordSAS - 1392021-06-14 14:43:52.0044562021-06-14 14:43:52.004456KeywordBloomberg - 1402021-06-14 14:43:52.0524502021-06-14 14:43:52.052450KeywordTableau - 1412021-06-14 14:43:52.0974512021-06-14 14:43:52.097451KeywordReuters - 1422021-06-14 14:43:52.1505032021-06-14 14:43:52.150503KeywordQuickbooks - 1432021-06-14 14:43:52.1915022021-06-14 14:43:52.191502KeywordSage - 1442021-06-14 14:43:52.5843032021-06-14 14:43:52.584303KeywordGoogle Sheets - 1452021-06-14 14:43:52.6312812021-06-14 14:43:52.631281KeywordNetSuite - 1462021-06-14 14:43:52.6782842021-06-14 14:43:52.678284KeywordDynamics 365 Finance - 1472021-06-14 14:43:52.7222852021-06-14 14:43:52.722285KeywordOracle - 1482021-06-14 14:43:52.7702842021-06-14 14:43:52.770284KeywordSAP - 1492021-06-14 14:43:54.7174182021-06-14 14:43:54.717418CategoryAccount Management - 1502021-06-14 14:43:54.7614212021-06-14 14:43:54.761421KeywordAccount Management - 1512021-06-14 14:43:54.8044222021-06-14 14:43:54.804422KeywordBusiness Account Management - 1522021-06-14 14:43:54.8574232021-06-14 14:43:54.857423AlignmentAccount Management2021-06-14 14:43:54.857423 - 1532021-06-14 14:43:55.1534532021-06-14 14:43:55.153453KeywordHuman Resources Information Systems (HRIS) - 1542021-06-14 14:43:55.2134232021-06-14 14:43:55.213423KeywordHuman Capital Management (HCM) systems - 1552021-06-14 14:43:57.4281652021-06-14 14:43:57.428165CategoryAccountability - 1562021-06-14 14:43:57.4701582021-06-14 14:43:57.470158KeywordAccountability - 1572021-06-14 14:43:57.5521622021-06-14 14:43:57.552162AlignmentAccountability2021-06-14 14:43:57.552162 - 1582021-06-14 14:43:57.7561662021-06-14 14:43:57.756166KeywordMS Office - 1592021-06-14 14:44:00.2931652021-06-14 14:44:00.293165StandardAmerican_Nurses_Association_Nursing_Scope_and_Standards - 1602021-06-14 14:44:01.2087332021-06-14 14:44:01.208733CertificationAAMA-CMA - 1612021-06-14 14:44:01.5207292021-06-14 14:44:01.520729CategoryAccounting - 1622021-06-14 14:44:01.5587312021-06-14 14:44:01.558731KeywordAccounting - 1632021-06-14 14:44:01.6047302021-06-14 14:44:01.604730KeywordMonth-End Close Processes - 1642021-06-14 14:44:01.7867522021-06-14 14:44:01.786752AlignmentAccounting2021-06-14 14:44:01.786752 - 1652021-06-14 14:44:02.4704422021-06-14 14:44:02.470442KeywordCrystal reports - 1662021-06-14 14:44:02.5344422021-06-14 14:44:02.534442KeywordIBM Cognos - 1672021-06-14 14:44:11.9239752021-06-14 14:44:11.923975KeywordPareto analysis - 1682021-06-14 14:44:11.9643682021-06-14 14:44:11.964368CertificationCertified_Coding_Specialist - 1692021-06-14 14:44:12.0143332021-06-14 14:44:12.014333CertificationCertified_Professional_Coder - 1702021-06-14 14:44:12.0643372021-06-14 14:44:12.064337CertificationRegistered_Health_Information_Administrator - 1712021-06-14 14:44:12.1153382021-06-14 14:44:12.115338CertificationRegistered_Health_Information_Technician - 1722021-06-14 14:44:12.4026452021-06-14 14:44:12.402645CategoryAccounting Management - 1732021-06-14 14:44:12.4476762021-06-14 14:44:12.447676KeywordAccounting Management - 1742021-06-14 14:44:12.5326482021-06-14 14:44:12.532648AlignmentAccounting Management2021-06-14 14:44:12.532648 - 1752021-06-14 14:44:12.7453692021-06-14 14:44:12.745369KeywordQuicken - 1762021-06-14 14:44:12.7944052021-06-14 14:44:12.794405KeywordSalesforce - 1772021-06-14 14:44:12.8393682021-06-14 14:44:12.839368KeywordOracle Applications - 1782021-06-14 14:44:12.8803992021-06-14 14:44:12.880399KeywordMicrosoft Dynamics - 1792021-06-14 14:44:14.5289652021-06-14 14:44:14.528965CategoryAccounting Softwares - 1802021-06-14 14:44:14.5910122021-06-14 14:44:14.591012KeywordAccounting Softwares - 1812021-06-14 14:44:14.6359822021-06-14 14:44:14.635982KeywordExcel - 1822021-06-14 14:44:14.6799782021-06-14 14:44:14.679978KeywordAccounting Software - 1832021-06-14 14:44:14.7549862021-06-14 14:44:14.754986AlignmentAccounting Softwares2021-06-14 14:44:14.754986 - 1842021-06-14 14:44:14.9859802021-06-14 14:44:14.985980KeywordMicrosoft Dynamics GP - 1852021-06-14 14:44:15.2361662021-06-14 14:44:15.236166KeywordMicrosoft Dynamics Great Plains - 1862021-06-14 14:44:15.4658142021-06-14 14:44:15.465814KeywordApple - 1872021-06-14 14:44:15.5218212021-06-14 14:44:15.521821KeywordMicrosoft - 1882021-06-14 14:44:16.3152912021-06-14 14:44:16.315291KeywordOracle E-Business Suite - 1892021-06-14 14:44:16.3652922021-06-14 14:44:16.365292KeywordOracle Grid Computing - 1902021-06-14 14:44:16.4202912021-06-14 14:44:16.420291KeywordOracle Real Application Clusters - 1912021-06-14 14:44:20.2557592021-06-14 14:44:20.255759CategoryAccounting Systems - 1922021-06-14 14:44:20.3037592021-06-14 14:44:20.303759KeywordAccounting Systems - 1932021-06-14 14:44:20.3627572021-06-14 14:44:20.362757KeywordADP - 1942021-06-14 14:44:20.4257552021-06-14 14:44:20.425755KeywordWorkday - 1952021-06-14 14:44:20.4897582021-06-14 14:44:20.489758KeywordERP - 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 - - - 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_Frameworkworkspace50,64,53,63,55,61,5778user@email.com - 29124e022-0723-4bf3-8bec-0a271616b5eaSELpublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 - 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_Skillspublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 - 49903442f-ed1e-42d4-8d95-858a26204d500published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 - 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_Skillspublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 - 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_Collectionpublished2021-10-01 09:00:00.00000078,77,7538 - 72938a728-f6e2-41a1-8a3b-9a838a56d212Characterpublished2021-10-01 09:00:00.00000078,77,76,7548 - - - 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 - 46a02ac8d-2e00-4fac-8fde-1f8237bdd769Large-Scale Web Application BuildBuild large-scale web applications using the .NET Framework with minimum coding.18Published2021-10-01 09:00:00.0000002,2,7,7,9,955,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 - 55cef80ee-5799-4f5c-89e5-8e4908419a50Service-Oriented Application BuildBuild service-oriented applications using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,7,7,10,1055,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 - 670b1fe1b-ecf1-4ca8-88ee-311d4d93ca67Application Domain CreationCreate application domains and assemblies using attributes, formatting and parsing base types, collections, events and exceptions, files and data streams, and generics.18Published2021-10-01 09:00:00.0000002,2,3,3,7,755,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 - 70a79c4b2-a715-4596-8211-b57e7e9e791aWindows-Based Application CreationCreate Windows-based applications using the .NET framework.18Published2021-10-01 09:00:00.0000002,2,7,7,11,1155,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 - 8c396acc6-9f88-484f-935d-8dbf9488c428Geometric Primitive Shape CombinationCombine geometric primitive shapes into digital 3D representations of a component of an object.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 - 9d59223d2-7a38-4146-8f4e-f226262bc2afGraphical Representation CreationCreate a 3D graphical representation of a physical object using specialized software.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 - 10ca32343a-1df3-4cb3-aa90-5dd6290ab248Layered Component IdentificationIdentify the layered components of a physical object that make up the complete digital three-dimensional (3D) rendering.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 - 117c9aff0f-0f53-4f92-b867-afe080da54a9System DesignDesign systems that facilitate trust and improved performance.208Published2021-10-01 09:00:00.00000021,21,22,2236,464,559,627,1521,36,464,559,627,1521 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 13a99e1dfe-afb6-4a6b-9dc0-ca2b94e653f2Students with Exceptionalities Instructional Material CreationCreate accessible instructional materials for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 - 14d6045810-24a8-43ab-b438-8d070952470bMode of Instruction CreationCreate alternate modes of instruction to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 15c1adeadc-96da-4003-84f4-fd2a96c9a399Students with Exceptionalities Mode of Instruction CreationCreate alternate modes of instruction to meet the needs of students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 - 16e8debbf4-e0c2-4558-bc03-1d9281af8fcfLearning Style Lesson CreationCreate lessons that meet different learning styles for students.238Published2021-10-01 09:00:00.00000024,25,37133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 17b5eb4473-12a9-41bf-bcc4-583ac3715602Instructional Material ReviewEnsure instructional materials are accessible.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,37,40,41,42,43,44143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 183235ee81-e69c-457f-b541-0b536d0312d6Language Aquisition MethodsIdentify appropriate teaching methods to address adult language acquisition.238Published2021-10-01 09:00:00.00000024,25,37137,482,565,584,585,586,637,655,1797 - 19f2dfedae-7828-4fb2-befb-1461d131e9cfAdult Learning StrategiesIdentify learning strategies that support adult learner needs.238Published2021-10-01 09:00:00.00000024,25,37137,482,565,835,1797 - 208eb6bd37-2198-42b2-a740-81b984249eddIEP ImplementationImplement accommodations documented in students' individualized education programs (IEPs).238Published2021-10-01 09:00:00.00000024,25,37133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 21ba45f2e0-7a07-423d-874a-cf44dd4a51d4Students with Exceptionalities ImplementationImplement accommodations for each student with exceptionalities so that they learn effectively based on their unique characteristics and circumstances.238Published2021-10-01 09:00:00.00000024,25,37136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 22312e3598-5d79-46e9-83b2-5a2cbdbc00dbStudents with Exceptionalities Instruction and Assessment ImplementationImplement accommodations with fidelity for classroom instruction.238Published2021-10-01 09:00:00.00000024,25,37136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 23c37c5681-70e0-4aa4-b2ad-4a8c47637be0Subtitle IncorporationIncorporate subtitles into videos used in curriculum.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,31,34,37,38,39,44143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 24a0e75e3c-2c46-423f-ba96-7bab1e16ab55Visual and Graphic 508 IncorporationIncorporate visual and graphic design principles based on Section 508 principles.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,31,34,36,37,38,39,44143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 25985ab415-30d7-42da-89e5-cf826f437e69Instrucitonal Resource IntegrationIntegrate instructional resources to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,38,39,44,45143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 262db0d5a7-ab53-4c2b-ab82-c7feee468a74Instructional Strategy IntegrationIntegrate instructional strategies to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,38,39,44,45143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 27bd4fe8db-e173-4f2e-815c-54bd4f140acdStudents with Exceptionalities Instructional Strategy IntegrationIntegrate appropriate instructional strategies for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 - 28f69f0099-effe-41dd-b244-6c56b0d4a95fInstructional Technology IntegrationIntegrate instructional technologies to meet the needs of learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,38,39,44,45143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 29365444df-bdbf-4bf4-9652-f4edeeaca72bAssessment and Testing ModificationModify assessments and testing conditions for learners who require accommodation.238Published2021-10-01 09:00:00.00000024,25,26,27,28,29,30,31,32,33,34,36,37,45,46143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 305655b01e-7d5b-490b-9946-cba49cef0023Students with Exceptionalities Assessment and Testing ModificationModify assessments and testing conditions for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 - 319df4810f-fe98-4cae-9892-a2396643daeaModify Assessment Conditions for Students with Language Learning NeedsModify assessments and testing conditions for students with language learning needs.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 - 32163af045-7f99-474e-a620-edee458ff8f8Integrate Technology for Students with ExceptionalitiesIntegrate appropriate technologies for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 - 336cbf4db6-17e8-44f5-8235-52de59774aa0Integrate Resources for Students with ExceptionalitiesIntegrate appropriate resources for students with exceptionalities.238Published2021-10-01 09:00:00.00000024,25,37123,125,126,129,134,135,136,480,481,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,2470,2471,2472 - 340b50baf3-2153-4757-b160-c5d94aa54070Implement Assessment AccommodationsImplement accommodations with fidelity for assessments.238Published2021-10-01 09:00:00.00000024,25,37136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 35d752a9ca-55d1-4220-8e74-d1743120e9c0Student With Exceptionalities AdvisingAdvise students with exceptionalities on academic issues that they may face.478Published2021-10-01 09:00:00.00000048,49,50136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 368cd1e0c0-c4ec-48a8-873a-b5a1f5d983fdGoal EstablishmentAssist students with identifying and establishing academic and professional goals.478Published2021-10-01 09:00:00.00000048,49,50122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 3784f9a1f8-c1e8-4ee3-b602-09194e2db361Student Development and Achievement PlanCreate a plan collaboratively to support student development and achievement.478Published2021-10-01 09:00:00.00000030,31,32,33,35,36,48,49,50,51,52123,125,126,129,134,135,136,143,146,148,480,481,483,484,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,843,846,851,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,1808,1813,2467,2468,2469,2470,2471,2472 - 38b82bfaea-eb56-40ed-99f2-6911e7b65901Adult Learner OpportunitiesExplore continued-learning opportunities for adult learners.478Published2021-10-01 09:00:00.00000048,49,50137,482,565,835,1797 - 39acf9865e-26ae-43e9-80f5-739ae186dcbbAdult Learner Support SystemsIdentify adult learners' educational needs with support systems based on work experience.478Published2021-10-01 09:00:00.00000048,49,50137,482,565,835,1797 - 40ec088d7f-031b-4bb4-ad29-5269ff1b23b9Academic Need IdentificationIdentify the academic needs of students in order to improve their knowledge or skills.478Published2021-10-01 09:00:00.00000048,49,50133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 41d3d54a52-9042-4f28-8cfc-88873c6e5da7Student and Family MentoringMentor students and families to achieve academic goals.478Published2021-10-01 09:00:00.00000030,31,32,33,36,48,49,50143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 426788a51d-6919-4ffa-b15c-e8219463f3a1Future PreparationPrepare students and families for the future by encouraging them to address learning needs.478Published2021-10-01 09:00:00.00000048,49,50133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 437814a1fb-a886-4076-94e8-5f1bda98e65aSelf Resource PromotionPromote oneself as a resource for students and their families.478Published2021-10-01 09:00:00.00000030,31,32,33,36,48,49,50,53,54,55,56123,125,126,129,134,135,136,143,146,148,480,481,483,484,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,843,846,851,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,1808,1813,2467,2468,2469,2470,2471,2472 - 446ec2f763-64c3-463d-8a3a-911c86394e02Conern ReponseRespond to student or family concerns.478Published2021-10-01 09:00:00.00000030,31,32,33,36,48,49,50123,125,126,129,134,135,136,143,146,148,480,481,483,484,565,786,787,790,791,792,793,794,795,796,807,808,824,825,826,827,828,829,830,831,832,833,834,843,846,851,1747,1748,1751,1752,1753,1754,1755,1756,1757,1768,1769,1785,1786,1787,1788,1789,1790,1795,1796,1808,1813,2467,2468,2469,2470,2471,2472 - 4521e0feef-6fc5-4861-95bb-ec4afd32bd9aSchool Resource ServiceServe as a resource in the school for students with exceptionalities and their families.478Published2021-10-01 09:00:00.00000048,49,50136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 467fbfa2ee-0474-4245-ad64-9f9069b2adc9Timeline and Planning RecommendationSuggest timelines and plans for academic work and study.478Published2021-10-01 09:00:00.00000048,49,50122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 47d986f648-5717-4283-a277-38e1a0af7ab7Student SupportSupport students in making appropriate choices relevant to their academic goals.478Published2021-10-01 09:00:00.00000048,49,50122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 48bf06dec1-cd48-40da-89df-07def4fa5592Self-Belief CultivationCultivate a belief in self, self-regulation, and perseverance to achieve educational goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 49c90ad0d1-e789-4acd-b106-850b4a573c3cLong-Term PerserveranceDemonstrate perseverance to attain long-term academic goals despite academic challenges.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,58,59,60,61,62,63,64,65,66136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 50ba7832fd-0e7f-45f1-817e-13488f583d5dWillingness and PerseveranceDemonstrate the willingness and perseverance to achieve long-term academic goals despite short-term setbacks.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,58,59,60,61,62,63,64,65,66,67,74,752,1,4,3 - 510d25a25f-413b-47a7-9b03-cdc52b69d6f3Long-Term Goal DevelopmentDevelop long-term goals despite short-term concerns.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,41,58,59,60,61,62,63,64,67,68174,489,567,913,1883,1884,1885,1886,1887 - 525f45bdcc-eeab-4cac-9b51-89bb0b605b26Student EncouragementEncourage students to remain committed to academic and professional goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,67,76,77122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 5316faefb8-dc18-45d6-bd8d-2265d5228eacMistake EvaluationEvaluate mistakes to reach long-term academic goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,67,68,74,781,2,3,4 - 54bdc11475-a2c9-4d7b-9dfc-ca2119a89fc5Adult Learner Persistence DevelopmentRecommend a means to overcome learning barriers for adult learners.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,35,36,41,42,58,59,60,61,62,63,64,65,66,68137,482,565,835,1797 - 553ecb3897-e1e3-4ec0-bb42-b3bdb7c0d0e0Thinking PatternsIdentify thinking patterns that interfere with persevering through short-term concerns or setbacks.578Published2021-10-01 09:00:00.00000027,29,30,31,32,33,36,41,42,58,59,60,61,62,64,65,66,67,74,78,791,2,3,4 - 5664dcd376-abdd-4167-a96d-3ae85659464cNursing PerseverencePersevere through challenges and setbacks toward nursing academic goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,64,65,66,67174,489,567,913,1883,1884,1885,1886,1887 - 57bf62682c-2ab5-4004-ae57-9d4725c412e6PersistencePersist along incremental steps toward achieving an academic goal.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,64,65,66,67,74,751,4,3,2 - 58c64c1844-874e-42ce-8537-5f2bfb539ea8PerserverancePromote perseverance as a positive quality.578Published2021-10-01 09:00:00.00000030,31,32,33,36,58,59,60,61,62,64,65,66,67122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 5976c5f61a-682e-421e-9c2d-5a504bdad20eGoal ReinforcementReinforce the importance of reaching academic and professional goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,42,58,59,60,61,62,65,66,67122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 60fb3dfbbb-aec8-4009-a6fe-8edc8c6e7c63Short-Term to Long-Term Education GoalsTransition short-term concerns to long-term or higher-order educational goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,67133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 610e8343c1-d9bc-4e1f-a7a7-5408818c8e77StrategiesImplement strategies to take the current situation into perspective and weigh reaction to current circumstances against positive consequences of achieving longer-term academic goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,41,58,59,60,61,62,74,781,2,3,4 - 62bad37fb3-a9a9-49f7-8bab-387184ba2a2bChallenge PerserveranceWithstand challenges and setbacks to persevere toward one's educational goals.578Published2021-10-01 09:00:00.00000030,31,32,33,36,40,41,58,59,60,61,62,65,66,67133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 634bddfe6b-fb94-47f7-bdea-5fd9b8321ff4Identify Thinking PatternsIdentify thinking patterns that interfere with perseverance.578Published2021-10-01 09:00:00.00000058,59,60,61,62,74,78,803,2,1 - 64816440ce-8a67-4980-9b8b-355dd21e2a3fEvaluate Mistakes to LearnEvaluate mistakes to further learning.578Published2021-10-01 09:00:00.00000058,59,60,61,62,74,78,801,2,3 - 656fe88d16-b003-4880-a644-36730fa74171Develop Adult Learner PersistenceDevelop adult learners' persistence through learning or life obstacles.578Published2021-10-01 09:00:00.00000058,59,60,61,62137,482,565,835,1797 - 66ffb662ca-2bd6-4d0c-a2ec-c0dceaaf9da7Develop Long-Term GoalsDevelop long-term goals despite short-term concerns.578Published2021-10-01 09:00:00.00000058,59,60,61,62174,489,567,913,1883,1884,1885,1886,18875 - 67fb8c9d06-faa8-42f1-b4e2-3ac468e69b15Professional LanguageConvey academic information using professional language.818Published2021-10-01 09:00:00.00000082,83174,489,567,913,1883,1884,1885,1886,1887 - 681f962e2f-3a2a-4310-be51-2cfb286ed7d0Teaching Structure, Style, and FormattingGuide students in using appropriate structures, style, and formatting for academic writing.818Published2021-10-01 09:00:00.00000082,83,84,85,86122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 69402a2737-e929-4de6-b82d-c584ad89fde8Adult Learner InstructionInstruct adult learners how to write using academic writing styles.818Published2021-10-01 09:00:00.00000082,83,85,86137,482,565,835,1797 - 7097b712d6-1715-4369-a7d2-60b880cff123Valid Data Source IdentificationInstruct students on how to effectively identify appropriate and valid data sources.818Published2021-10-01 09:00:00.00000082,83,84122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 712033cce3-eb7c-4c47-9276-424480c6b5eaArgument Presentation InstructionInstruct students on how to present arguments logically and factually.818Published2021-10-01 09:00:00.00000082,83,84122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 7256f73c31-fa90-4052-9fea-ed6aa4a3fdbePosition SupportApply a formal writing style, employing evidence to support one's position.818Published2021-10-01 09:00:00.00000082,83,85,86133,134,135,481,565,822,823,824,825,826,827,828,1783,1784,1785,1786,1787,1788,1789 - 736ae74dcc-d3f6-4b70-88ab-64db76e07e1aScholarly ConversationApply effective writing skills to convey ideas, make arguments, and engage in scholarly conversation.818Published2021-10-01 09:00:00.00000082,83,85,86136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 7448a7c96c-187f-45ab-b0f9-441319ed332bEvidence-Based ReasoningWrite using evidence-based reasoning.818Published2021-10-01 09:00:00.00000082,8354,174,489,567,913,1883,1884,1885,1886,1887 - 75e49fdbb4-2d3e-4fee-953a-dd46d7e34fd1Recognize Views of OthersRecognize that others will think differently and will hold different views, interests, and beliefs.878Published2021-10-01 09:00:00.000000886,7 - 76b07500ff-abb9-4616-aa3d-52114b0ac182Exchange IdeasExchange ideas freely.878Published2021-10-01 09:00:00.000000887 - 77952777f9-e5f9-4ade-9a03-c70366c49fe5Free from PrejudiceBe free of prejudice and discrimination.878Published2021-10-01 09:00:00.000000886,7 - 7830045c0e-91e5-4afb-8c61-d81952a821edAppreciate DiversityAppreciate the richness of diversity, diverse ideas, and diverse communities.878Published2021-10-01 09:00:00.000000886,7 - 79adc069c3-881d-4c5d-a2e0-3f021adffc88Gap AnalysisConduct a gap analysis between actual deliverables and acceptance testing requirements.898Published2021-10-01 09:00:00.00000090,91,9238,43,464,559,632,637 - 809ce973e6-4402-44e7-88cc-63cfe8b71751Status Report CreationCreate a status report for contract deliverables.898Published2021-10-01 09:00:00.00000090,91,9238,43,464,559,632,637 - 812617d28b-2c18-42ff-9ab1-6f020770f00eDesignDesign test plans, scenarios, scripts, or procedures for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,656,665,668 - 825e6f6f95-20fc-43aa-996a-199427ba7473Specifications and ProceduresDetermine acceptance testing specifications and procedures from existing documentation.898Published2021-10-01 09:00:00.00000090,92,93,94,95,96,97,98,99,100,101,102,10383,85,469,470,561,696,701,702,703,704,705,706,707,708,709,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484 - 83cdf754f4-e161-44ba-b68d-0a8c1a62eaebStandard DevelopmentDevelop standards, methods, and procedures to evaluate product quality or release readiness for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,665,668,2485 - 8406cdf44d-0ce3-477b-9e1a-eeacba6ab10fStandard DocumentationDocument standards, methods, and procedures to evaluate product quality or release readiness for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,665,668,2485 - 85812dcb2f-1aa4-4039-8177-b83655e45594Test DocumentationDocument test procedures to ensure replicability and compliance with standards for acceptance testing.898Published2021-10-01 09:00:00.00000090,9254,55,58,59,466,560,654,655,665,668,2486 - 8656ff1f06-e1e3-4dc8-b3f0-8dfc7bd385b6Requirement GenerationGenerate a list of acceptance testing requirements.898Published2021-10-01 09:00:00.00000090,91,92,104,10538,43,464,559,632,637 - 87fbab883f-d79f-47c2-b496-1ed749bc39beProduct Dimension MeasurementMeasure dimensions of products to verify conformance acceptance testing specifications.898Published2021-10-01 09:00:00.00000090,92,93,94,95,96,97,98,99,100,101,102,10383,85,469,470,561,696,701,702,703,704,705,706,707,708,709,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484 - 8842703f26-b67f-4001-8ea8-18ea3f01e8a3Inspection RecordRecord inspection or test data and acceptance testing status.898Published2021-10-01 09:00:00.00000090,92,93,94,95,96,97,98,99,100,101,102,10383,85,469,470,561,696,701,702,703,704,705,706,707,708,709,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484 - 89545377ac-3618-4c65-afef-0c255351ad89Acceptance Test Data Variations DefinitionDefine variations in data that are possible for an acceptance testing script.898Published2021-10-01 09:00:00.00000090,92,10654,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 - 90bb6a57c6-0779-46c7-b64a-0f6bb7827e70Determine Acceptance Testing DiscrepanciesDetermine if there are discrepancies between original software specifications and final acceptance testing scenarios.898Published2021-10-01 09:00:00.00000090,90,92,92,107,10754,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493,54,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 - 9115bec8cc-83ec-4722-a1fd-cf67eb4c9c1dResolve User Concerns During Acceptance TestingResolve end users' concerns during acceptance testing processes.898Published2021-10-01 09:00:00.00000090,9254,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 - 92438be742-fe7c-48f0-82d1-e70a1b882d25Acceptance Testing Script Failure DocumentationDocument acceptance testing script failures.898Published2021-10-01 09:00:00.00000090,92,10854,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 - 93c44f0a53-f9f4-46e9-beb3-66b6495c4ee5User Acceptance Testing (UAT) Workshops ManagementManage user acceptance testing (UAT) workshops.898Published2021-10-01 09:00:00.00000090,92,10954,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 - 9473ec441f-7c07-42d2-98c8-c8461e7f7c38User Experience Acceptance Test DesignDesign alterations to user experience components to meet acceptance testing criteria.898Published2021-10-01 09:00:00.00000090,90,92,92,110,110,111,11158,466,560,667,2494,58,466,560,667,2494 - 9570a30c21-b47e-49d1-87ed-5c51497259b5Data Architecture Acceptance Test DesignDesign alterations to data architecture components to meet acceptance testing criteria.898Published2021-10-01 09:00:00.00000090,92,11257,466,560,661,2494 - 96f529adfd-0cfa-480a-a39b-847636c62639Medical Record AccessAccess relevant medical records needed to protect health information.1138Published2021-10-01 09:00:00.000000114,115114,476,563,771,772,773,1732,1733,1734 - 977e167ecb-6808-4749-93a5-8297d7c9882aProgram and Resource DeterminationDetermine appropriate computing programs and online resources.1138Published2021-10-01 09:00:00.000000114,115,116,11754,122,123,125,126,127,128,129,131,198,466,480,495,560,565,569,655,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778,2488 - 98b7519fda-0e4d-4ff2-9307-f03a3a83bb08Policy EnforcementEnforce policies regarding online resources.1138Published2021-10-01 09:00:00.000000114,11554,122,123,125,126,127,128,129,131,198,466,480,495,560,565,569,655,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778,2488 - 992d61fdd0-2ae6-4e62-9bcc-1a1b635ed532HIPAA ImplementationImplement Health Insurance Portability and Accountability Act (HIPAA)-compliant concept of minimum and necessary user access for the role of the worker.1138Published2021-10-01 09:00:00.000000114,115114,476,563,769,771,772,773,1730,1732,1733,1734 - 10049bf2af4-d834-4af9-bbcd-64c1fe59fc0aStudent Resource CommunicationInform students of online resources for guidelines and policies.1138Published2021-10-01 09:00:00.000000114,11554,122,123,125,126,127,128,129,131,466,480,560,565,569,655,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778,2488 - 1010e2014a3-2076-4f49-a60e-04b273952effResource MonitoringMonitor computing resource use and abuse.1138Published2021-10-01 09:00:00.000000114,115122,123,125,126,127,128,129,131,198,480,495,565,569,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 10210913e85-83f1-4556-8fff-4213f3b4cf57Network Router Performance MonitoringMonitor network routers for performance issues.1188Published2021-10-01 09:00:00.000000119,120,121,12256,57,466,560,657,659,662,2489,2490,2495,2496 - 10378d61a82-8302-488c-9c3f-bf01d88e5ff9Network Router Security MonitoringMonitor network routers for security issues.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,124,12456,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 104f5b83170-bff2-4bff-93eb-660a2a9f6653Network Routers Security ConfigurationConfigure security on network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,125,12556,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 105b749ad2f-465a-41a3-92be-ba7072ce09b2Router Network Traffic ConfigurationConfigure network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,119,122,122,122,125,125,125,126,126,12656,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 106a3fe184d-921a-45f6-a384-308ca77b4498Network Connection DesignDesign a network connection between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,127,127,128,12856,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 108aa3b83b9-1d08-4ada-8c3a-8034500da009Financial Data ComparisonCompare financial data against third-party statements to confirm balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,136,137,138,139,140,141,142,14349,52,465,559,644,645,646,647,651,652 - 109913ed1f1-cca5-47b7-bf7e-a3a3af63ad6cReconciliationConduct periodic reconciliations of financial account balances to ensure accuracy.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,136,137,138,139,140,141,142,14349,52,465,559,644,645,646,647,651,652 - 110ba97364c-4d8d-4da2-bf07-4279d5255535Financial AdjustmentsCreate financial adjustments to address account discrepancies.1298Published2021-10-01 09:00:00.00000091,130,131,132,136,142,144,145,146,147,1487,9,462,558,589,590,592,1461,1462,2498,2499 - 111543dfbaf-d753-4add-b061-0b838dce7c6dCash Guideline and Policy CreationCreate guidelines and policies around cash processes that are adequate and effective to prevent significant errors in calculating cash balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1123b557765-d719-4a71-9b16-e40eff12d81cInternal Process DesignDesign enterprise-wide internal processes to manage reconciliation of accounts, ensuring internal audit compliance.1298Published2021-10-01 09:00:00.000000130,131,132,134,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1135b351b80-3c20-4f69-b2a8-9b4c890f0fbbInternal Process ImplementationImplement enterprise-wide internal processes to manage reconciliation of accounts, ensuring internal audit compliance.1298Published2021-10-01 09:00:00.000000130,131,132,134,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 114ed718562-96cc-409c-a949-7e4702db5f30Account Invoice and Payment MatchingMatch account invoices with recorded payments in an accounting system.1298Published2021-10-01 09:00:00.00000091,130,131,132,134,135,136,142,144,145,146,147,1487,9,462,558,589,590,592,1461,1462,2498,2499 - 11526746e9b-67d3-4a0e-84a6-1f5aa74ff77fFinancial Data RecalculationRecalculate financial data to verify valuation of account balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,136,137,138,139,140,141,142,14349,52,465,559,644,645,646,647,651,652 - 116a7bd2eee-4d7e-4686-a241-209b3377a499Entry Error ResolutionResolve entry errors and reconciles ledgers to ensure cash amounts agree with bank balances.1298Published2021-10-01 09:00:00.000000130,131,132,134,135,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1171e0f0efe-723b-4736-824e-fbb78c1157e9Aging ReportsRun aging reports to compare invoices against variable payment terms on an account.1298Published2021-10-01 09:00:00.00000091,130,131,132,134,135,136,142,144,145,146,147,1487,9,462,558,589,590,592,1461,1462,2498,2499 - 118ace9e8ac-802f-4388-b845-221b4343698fAnalyze Processes and Systems for ImprovementsAnalyze current processes and systems for efficiency and process improvements.1298Published2021-10-01 09:00:00.000000130,131,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 119be0c058e-58b9-4651-b396-5576cb3a0231User SimulationAct as a user within many domains, networks, and cloud subscriptions.1498Published2021-10-01 09:00:00.000000150,151,15254,466,560,655,2488 - 12040c30943-f9e4-4b15-819e-126c25cdde41Application InteractionInteract with applications, networks, and data in a predefined manner.1498Published2021-10-01 09:00:00.000000150,151,15254,466,560,655,2488 - 121ab2a77fa-ff91-4d7a-9822-3fe787171c86Policy DevelopmentDevelop policies detailing proper uses of system and user accounts for human resource�related systems.1498Published2021-10-01 09:00:00.000000150,151,152,153,15436,464,559,627,629 - 122b5ce2cb4-8628-45f6-b325-11c2e8ff42f5User Account EstablishmentEstablish system and user accounts for new employees.1498Published2021-10-01 09:00:00.000000150,151,152,153,15436,464,559,627,629 - 1232a0d0b6b-82c4-494b-8540-29c43745d3f8Employee Account MainteanceMaintain employee accounts and records, including updates to such information.1498Published2021-10-01 09:00:00.000000150,151,152,153,15436,52,464,465,559,627,629,651,652 - 124c3068e15-dae5-4b5f-ad92-5927737962dfDevice Configuration ManagementManage configuration of and access to applications on a device.1498Published2021-10-01 09:00:00.000000150,151,15254,466,560,655,2488 - 12521c640f7-e87c-47c2-b985-70e3dee34602Organizatonal Policy UseImplement organizational policies to identify the criteria by which customer accounts are designated and classified to rank them, accommodate the account, and mitigate concerns.1498Published2021-10-01 09:00:00.000000150,151,1521,2,4,5,7,10,12,17,27,30,35,38,43,54,223,227,228,460,461,462,463,464,466,503,506,558,559,560,571,572,581,582,584,585,586,589,593,595,600,614,618,626,632,637,655,1024,1036,1448,1450,1452,1453,1454,1457,1464,1471,1477,1494,1500,1520,1528,1533,2021,2033,2488,2500,2501 - 126a400b351-94d6-488a-b443-5f7f16a44322Strategic Plan ExaminationExamine the organization's strategic plan and long-term objectives to define the criteria for key account status and develop a procedure to establish benefits for accounts with key account management status.1498Published2021-10-01 09:00:00.000000150,151,1521,2,5,7,10,12,17,27,30,35,38,54,223,227,228,460,461,462,463,464,466,503,506,558,559,560,571,572,581,582,586,589,593,595,600,614,618,626,632,655,1024,1036,1448,1450,1454,1457,1464,1471,1477,1494,1500,1520,1528,2021,2033,2488,2500,2501 - 127424856e1-6fdb-4da0-a79a-8258f2e8d958Cross-Functional Team CollaborationCollaborate with a cross-functional team to evaluate which accounts are the best fit for the range of products and services the company offers, and which pose the biggest risk in impacting the company's bottom line.1498Published2021-10-01 09:00:00.000000150,151,1521,2,4,5,7,10,12,17,27,30,35,38,43,223,227,228,460,461,462,463,464,503,506,558,559,571,572,581,582,584,585,586,589,593,595,600,614,618,626,632,637,1024,1036,1448,1450,1452,1453,1454,1457,1464,1471,1477,1494,1500,1520,1528,1533,2021,2033,2500,2501 - 1284ec33d34-566e-4db2-b4a7-63aa4480ee26Plan DevelopmentDevelop a key account management plan that includes a vision, mission, and strategic objectives aligned to customer marketing and sales strategy.1498Published2021-10-01 09:00:00.000000150,151,1521,2,4,5,7,10,12,17,27,30,35,38,43,223,227,228,460,461,462,463,464,503,506,558,559,571,572,581,582,584,585,586,589,593,595,600,614,618,626,632,637,1024,1036,1448,1450,1452,1453,1454,1457,1464,1471,1477,1494,1500,1520,1528,1533,2021,2033,2500,2501 - 129ffd8019a-8f1f-4f2f-b8a4-a5603347f3cdMedical Error CommunicationCommunicate medical errors promptly with transparency and honesty to the attending provider and organization.1558Published2021-10-01 09:00:00.000000156,157174,489,567,913,1883,1884,1885,1886,1887 - 130c03a07ed-97cd-4c71-aa0f-5a8111d432a6Employee Action CorrectionCorrect employees actions when their results do not meet expectations.1558Published2021-10-01 09:00:00.000000156,157,15875,76,83,85,469,470,561,687,688,689,696,701,702,703,704,705,706,707,708,709,1611,1612,1613,1614,1615,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2502,2503,2504 - 1319bb2a948-6664-4560-aed0-f160dc80a94aSchool Policy AdherenceDemonstrate responsibility for their job duties by adhering to school and district policies.1558Published2021-10-01 09:00:00.000000156,157136,481,565,829,830,831,832,833,834,1790,1795,1796,2470,2471,2472 - 1325ba3dd8e-7e50-467f-aaea-9b81c61384f8Information DisclosureDisclose relevant information to students, colleagues, and administrators.1558Published2021-10-01 09:00:00.000000156,157137,482,565,835,1797 - 133a0afb45f-7f53-41b8-a64a-4988511bf1feRationale for ActionsExplain the rationale for actions taken toward students, colleagues, or administrators.1558Published2021-10-01 09:00:00.000000156,157137,482,565,835,1797 - 13464ba523a-c6d7-48d8-bff7-199189d859d3Rationale for DecisionsExplain the rationale for decisions made to students, colleagues, or administrators.1558Published2021-10-01 09:00:00.000000156,157137,482,565,835,1797 - 1359e6a56ad-267a-4bc1-9f79-1a78eaace39fIntegrity for DecisionsMaintain integrity for decisions, behavior, and actions of self, students, faculty, and staff of the organization.1558Published2021-10-01 09:00:00.000000156,157122,123,125,126,127,128,129,131,480,565,785,786,787,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,812,813,814,815,816,817,1746,1747,1748,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1773,1774,1775,1776,1777,1778 - 136e069470c-d95b-4c37-ad3a-25d0fda3b81eEmployee Performance MeasurementMeasure employee performance against goals.1558Published2021-10-01 09:00:00.000000156,157,15875,76,83,85,469,470,561,687,688,689,696,701,702,703,704,705,706,707,708,709,1611,1612,1613,1614,1615,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2502,2503,2504 - 137c6433604-e4f2-4801-9a49-64903581fcb6Collective ResponsibilityTake collective responsibility for a total organization's successes and failures within the scope of influence.1558Published2021-10-01 09:00:00.00000030,31,32,33,36,40,41,43,67,68,156,157143,146,483,484,565,843,846,1806,1808,2467,2468,2469,2505 - 138f9828ece-14e7-4485-a01a-1036777ee6b6Personal Decision OwnershipTake ownership of personal decisions regardless of the outcome.1558Published2021-10-01 09:00:00.000000156,157,15875,76,83,85,469,470,561,687,688,689,696,701,702,703,704,705,706,707,708,709,1611,1612,1613,1614,1615,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1647,1648,1650,1651,1652,2464,2465,2466,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2502,2503,2504 - 139db5bc08d-9bb6-45d6-95c6-0ff839135451Medical Practice Compliance EvaluationEvaluate current medical practices to ensure compliance with regulations.1558Published2021-10-01 09:00:00.000000156,157,159112,113,168,177,476,489,563,567,759,762,766,900,916,1720,1723,1727,1866,18905 - 14060766fb3-7933-4bff-b0fe-f7c4fcabcbc2Peer Performance Expectation CommunicationCommunicate performance expectations with peers.1558Published2021-10-01 09:00:00.000000156,157,159112,113,168,177,181,476,489,563,567,759,762,766,900,916,936,1720,1723,1727,1866,1890,25065 - 141a2fcf893-cf0e-4c58-9559-e7344aaddd7cTeam Expectation VerificationVerify team members meet expectations.1558Published2021-10-01 09:00:00.000000156,157,159112,113,168,177,181,476,489,563,567,759,762,766,900,916,936,1720,1723,1727,1866,1890,25065 - 142cfc99fa0-609c-4b6a-8364-9c84af0605a8Medication Medical Order VerificationVerify medical orders before dispensing medications.1558Published2021-10-01 09:00:00.000000156,157,159,160112,168,181,197,476,489,494,563,567,568,762,900,936,976,1723,1866,1966,25065 - 1434e15deeb-a0cb-4f36-9146-ddc8a8815262Economic Movement AnalysisAnalyze the economic movement within an organization, documenting and communicating trends and summaries.1618Published2021-10-01 09:00:00.000000132,133,134,135,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,204,462,463,464,465,467,473,474,497,558,559,560,562,569,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 14431a87113-9bee-444a-8314-f4d8a316b869Economic Status CommunicationCommunicate the economic status and trajectory of an organization to key stakeholders.1618Published2021-10-01 09:00:00.000000132,133,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,204,462,463,464,465,467,473,474,497,558,559,560,562,569,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 145d9b6893f-3373-4f6f-9c79-f7e4f7b9dd33Journal Entry CreationCreate a journal entry in an accounting system.1618Published2021-10-01 09:00:00.00000028,29,43,91,132,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 - 1467e2700dd-092a-42ff-bbcc-4de5225fb4e1General Ledger DefinitionDefine an organization's general ledger.1618Published2021-10-01 09:00:00.00000091,132,142,145,146,147,148,162,163,1649,32,38,43,45,47,48,50,52,62,63,97,108,204,462,464,465,467,473,474,497,558,559,560,562,569,592,620,621,622,632,637,639,642,643,648,651,671,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1587,1588,1685,1712,2497,2498,2507 - 147a4cd8fbd-ce21-4f4f-aa60-cbd28fc5da60Economic Cost DefinitionDefine the economic cost of a project for an organization.1618Published2021-10-01 09:00:00.000000132,133,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,462,463,464,465,467,473,474,558,559,560,562,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 148de76aa08-cad9-43d7-a675-f8b4e2c8c0b5Accounting Models DevelopmentDevelop accounting models for forecasting inventory needs, orders, and profitability.1618Published2021-10-01 09:00:00.000000132,133,162,163,1641,2,7,8,9,10,11,12,13,17,23,30,460,462,463,558,581,582,591,592,593,594,595,596,600,610,618,1448,1449,1450,1460,1461,1462,1464,1465,1466,1467,1468,1469,1470,1471,1473,1477,1488,1500,1501,1502,1503,1504,1505,1506,2498,2509,2510,2511,2512,2513,2514,2515 - 1498a33373d-0091-4dc3-ad5e-773fb3b6bca7Business Processes DevelopmentDevelop business processes for financial systems.1618Published2021-10-01 09:00:00.00000091,132,133,134,135,142,145,146,147,148,162,163,1649,32,38,43,45,47,48,50,52,62,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,671,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1587,1588,1685,1712,2497,2498,2507 - 1504b986f4c-b49e-46a8-a1d8-05e61e78697fClosing Procedures EstablishmentEstablish accounting closing procedures in compliance with generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.000000132,134,162,163,1641,2,9,10,11,12,13,23,30,204,460,462,463,497,558,569,581,582,592,593,594,595,596,610,618,1448,1449,1450,1461,1462,1464,1465,1466,1467,1468,1469,1470,1471,1473,1488,1500,1501,1502,1503,1504,1505,1506,2498,2509,2510,2511,2512,2513,2514,2515 - 151cf5de322-52e0-42ec-9f5f-1eb6b932bf32Full Cycle Financial AccountingExecute full cycle financial accounting, inclusive of accounts receivable, accounts payable, and payroll.1618Published2021-10-01 09:00:00.000000132,162,163,1641,2,5,7,9,10,12,17,27,30,35,36,38,43,45,47,48,50,52,63,97,108,223,227,228,460,461,462,463,464,465,467,473,474,503,506,558,559,560,562,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,627,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 - 152ffe4341a-f032-42ac-9e53-8e54ef2233ccBest Practices ImplementationImplement financial best practices of the specific business.1618Published2021-10-01 09:00:00.00000091,132,134,135,142,145,146,147,148,162,163,1649,32,38,43,45,47,48,50,52,62,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,671,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1587,1588,1685,1712,2497,2498,2507 - 1536ee5dd79-e607-4381-8446-41f3372b2436Closing Procedure ImplementationImplement month-end and year-end closing accounting procedures for an organization.1618Published2021-10-01 09:00:00.00000028,29,43,132,134,162,163,1641,2,9,10,11,12,13,14,15,23,27,30,204,460,462,463,497,558,569,581,582,592,593,594,595,596,597,598,610,614,618,1448,1449,1450,1461,1462,1464,1465,1466,1467,1468,1469,1470,1471,1473,1474,1475,1488,1494,1500,1501,1502,1503,1504,1505,1506,2498,2509,2510,2511,2512,2513,2514,2515 - 1548aefe35f-03e9-4b01-8a89-0e5e3f368d9fAccounting Operations LeadershipLead accounting operations and the preparation of financial reports to ensure the accurate and timely dissemination of financial statements and budget reports.1618Published2021-10-01 09:00:00.000000132,162,163,1641,2,5,7,9,10,12,17,27,30,32,35,36,38,43,45,47,48,50,52,63,97,108,223,227,228,460,461,462,463,464,465,467,473,474,503,506,558,559,560,562,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,627,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 - 15528be12cb-12e2-47ec-a8fd-546c97662509Account Reconciliation ProcessesPerform account reconciliation processes at year-end.1618Published2021-10-01 09:00:00.00000028,29,43,91,132,134,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 - 1569eaca429-0ac5-408f-8ad6-b27c56f2f973General Ledger PreparationPrepare a general ledger for an organization.1618Published2021-10-01 09:00:00.00000028,43,91,132,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 - 157da166158-28f2-4d78-a925-af3bd97dc22fFinancial Report PreparationPrepare financial reports in accordance with generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.00000028,29,43,91,132,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 - 158dbdcd291-f1ce-4eec-a64d-994c8ea73acbFinancial Statement PreperationPrepare financial statements in accordance with generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.00000029,43,91,132,134,143,147,148,162,163,164,165,16635,36,37,38,41,42,44,45,47,48,49,50,52,204,464,465,497,559,569,626,627,630,631,632,635,636,639,642,644,645,646,647,648,651,652,2508 - 1598c351161-045f-472a-9b10-11975643c8efReconciliation Schedules PreparationPrepare reconciliation schedules for balance sheet accounts, including accounts receivable and bad debt reserves.1618Published2021-10-01 09:00:00.000000132,134,162,163,1641,2,5,7,9,10,12,17,27,30,32,35,36,38,43,45,47,48,50,52,63,97,108,204,223,227,228,460,461,462,463,464,465,467,473,474,497,503,506,558,559,560,562,569,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,627,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 - 160fe0a9a50-0c52-40bf-8cd4-1b06bfdb396aEconomic Movement ProcessProcess the economic movement within an organization.1618Published2021-10-01 09:00:00.000000132,133,134,162,163,1649,30,32,38,43,45,47,48,50,52,63,97,108,204,462,463,464,465,467,473,474,497,558,559,560,562,569,592,618,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1502,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 161b775653f-98ee-4e46-8eea-ec5ce6a5d5d3Day-to-Day RecordingRecord the day-to-day financial transactions to ensure complete, accurate, and timely financial statements while reconciling discrepancies.1618Published2021-10-01 09:00:00.000000132,162,163,1641,2,5,7,9,10,12,17,27,30,32,35,38,43,45,47,48,50,52,63,97,108,204,223,227,228,460,461,462,463,464,465,467,473,474,497,503,506,558,559,560,562,569,571,572,581,582,586,589,592,593,595,600,614,618,620,621,622,626,632,637,639,642,643,648,651,672,732,753,1024,1036,1448,1450,1454,1457,1461,1464,1471,1477,1494,1500,1508,1509,1510,1520,1521,1528,1533,1543,1544,1549,1552,1588,1685,1712,2021,2033,2497,2498,2500,2501,2507 - 16226a02cf5-31c9-43f7-b017-043f0cab8b85Account Balances AdjustmentAdjust account balances from cash basis to accrual basis and presents month-end results according to generally accepted accounting principles (GAAP).1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,204,465,497,559,569,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1637bc2d16d-6e7c-44f8-859b-0aac2c320bafFinancial Reviews ConductionConduct financial reviews of month-end reports for accuracy to communicate discrepancies.1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,204,465,497,559,569,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 164a785ef66-12d2-49a7-b8a1-19bfe298e837Standard Procedures DevelopmentDevelop standard procedures and cross-training to streamline processes, increase accuracy, and decrease overall month-end closing duration.1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 165bab8efa3-3627-49db-b076-8bc74d469ac1Improvement RecommendationsRecommend improvements to senior management on internal control and audit of the month-end close process.1618Published2021-10-01 09:00:00.000000132,134,162,163,16445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 16618282ff8-f4b5-435b-b5ca-4dff4001448eMedical Claim ProcessingProcess a medical claim through the financial cycle.1618Published2021-10-01 09:00:00.000000162,164187,188,490,567,955,956,1942,25165 - 167400d467c-b747-4c3d-9631-9648cce5c7c9Medical Facility Account ConsolidationConsolidate financial accounts for a medical facility.1618Published2021-10-01 09:00:00.000000132,134,162,164187,188,490,567,955,956,1942,25164,5 - 168437ee270-5c0c-4c26-a007-77d866acfffcUnbilled Medical Procedure Financial Impact ExplanationExplain the financial impact to a facility given unbilled medical procedures.1618Published2021-10-01 09:00:00.000000132,133,134,162,164,167,168,169,170,171187,188,490,567,955,956,1942,25164,5 - 169b0a3978a-e54e-4089-9564-45c5cf7bac17Accounting Trend AnalysisAnalyze current accounting trends to design models to establish cost-effective budgets for future projects.1728Published2021-10-01 09:00:00.000000132,133,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 170f604b5d2-0fcf-4cbd-830d-5db6d51ea570Cash Flow Report CreationCreate a cash flow report for an organization.1728Published2021-10-01 09:00:00.00000091,132,133,142,173,174,175,176,177,17810,13,30,462,463,558,593,596,618,1464,1465,1466,1467,1468,1469,1473,1500,1501,1502,1503,1504,1505,1506,2509,2513,2514,2515 - 171ac9f004d-4cc2-4149-b395-f02023c13c45Annual Budget DevelopmentDevelop an annual budget for an organization's expenses.1728Published2021-10-01 09:00:00.00000091,132,133,142,173,174,175,176,177,17810,13,30,462,463,558,593,596,618,1464,1465,1466,1467,1468,1469,1473,1500,1501,1502,1503,1504,1505,1506,2509,2513,2514,2515 - 1728a77812d-1983-4639-8c7e-ab74e542f5b8Company-Wide Plan DevelopmentDevelop company-wide plans to reduce financial risks and lower costs that align to generally accepted accounting principles (GAAP) methodologies.1728Published2021-10-01 09:00:00.000000132,134,135,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1730a6fcfde-e53c-4df4-8557-7f8409c3d8f2Company-Wide Plan ImplementationImplement company-wide plans to reduce financial risks and lower costs that align to generally accepted accounting principles (GAAP) methodologies.1728Published2021-10-01 09:00:00.000000132,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 174a2a1fd33-a0fb-4831-9f47-9e260f6a0ac7Anticipated Revenue ForecastingForecast anticipated revenue compared to expenses.1728Published2021-10-01 09:00:00.00000091,132,133,142,173,174,175,176,177,17810,13,30,462,463,558,593,596,618,1464,1465,1466,1467,1468,1469,1473,1500,1501,1502,1503,1504,1505,1506,2509,2513,2514,2515 - 17594ca5450-fb14-4768-883f-1d98abfbae6fProper Accounting Methods EnforcementEnforce proper accounting methods and policies to ensure positive overall company financial health.1728Published2021-10-01 09:00:00.000000132,134,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 17638b32fbd-99b1-41c9-a59c-3e2c9c68c6a9Financial Statement ReviewReview financial statements to identify discrepancies and make corrections.1728Published2021-10-01 09:00:00.000000132,134,135,173,17445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 177b8ff2c61-3be8-46df-b088-ba0b9f97c044Cash Flow AnalysisAnalyze cash flows in spreadsheet software using macros for advanced data manipulation.1798Published2021-10-01 09:00:00.000000132,133,134,142,180,181,182,18345,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 178ad0eb9b3-8266-4b1a-87cc-29c68bb19d69General Ledger Entry CreationCreate general ledger entries in accounting and spreadsheet software.1798Published2021-10-01 09:00:00.000000132,142,180,181,182,183,18445,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 179903acd86-a7af-4645-b416-a5aa58d8632fTrend Forecast DesigningDesign trend forecasts using accounting software.1798Published2021-10-01 09:00:00.000000132,133,134,135,142,180,182,183,18545,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 180da2555ac-9201-4436-9db6-fc0d8a7e5026Accounting Software Solution EvaluationEvaluate for the best accounting software solution to meet the needs of the organization.1798Published2021-10-01 09:00:00.000000132,134,135,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 18117edf36a-1f31-4c84-9335-9b430b83eba5Accounting Software Solution ImplementationImplement the best accounting software solution to meet the needs of the organization.1798Published2021-10-01 09:00:00.000000132,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 182ae976d9d-8ca2-4620-9e24-2e567d9e4be9Accounting Activities ExecutionExecute accounting activities utilizing applications to meet financial reporting and tax requirements.1798Published2021-10-01 09:00:00.000000132,142,147,180,182,183,186,187,188,189,1909,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 183ddcfed51-77f9-4165-a6aa-34de0cefe39cFinancial Transactions ExportationExport financial transactions using accounting software.1798Published2021-10-01 09:00:00.00000091,132,133,134,135,143,147,148,165,166,180,182,18345,47,49,52,465,559,639,642,644,645,646,647,651 - 1845e50454e-8096-4bc6-8dd4-5162ed8adc60Assets IdentificationIdentify assets, income, and expenses by using an accounting tracking system.1798Published2021-10-01 09:00:00.00000091,132,133,134,135,143,147,148,165,166,180,182,18345,47,49,52,465,559,639,642,644,645,646,647,651 - 1851ca4f89c-0da9-4574-a79a-bfff9b57cc7cSoftware Implementation Process ImprovementImprove accounting software implementation processes to simplify enterprise-wide installation and reduce overall installation time.1798Published2021-10-01 09:00:00.000000132,142,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 1863f04a22e-c9e1-44a3-ad54-f25ca674a1adSoftware Platform Development and Implementation LeadershipLead the development and implementation of a software platform to provide a secure and accurate platform for calculating revenue, cash flow, and payroll.1798Published2021-10-01 09:00:00.000000132,142,180,182,18345,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1879c47b1aa-fe14-4c2f-ae1f-1695b16cdc4dAccounts Payable and Receivable ManagementManage accounts payable and receivable, advanced cost accounting, environmental accounting, and reporting transactions with an accounting software.1798Published2021-10-01 09:00:00.000000132,142,147,180,182,183,186,1879,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1540,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 188125049c9-c0b8-4559-b936-7209c2c4b337"Centers" Feature of QuickBooks NavigationNavigate the "Centers" feature of QuickBooks to execute various tasks related to customers, including using analysis from insights and setting up charts of accounts.1798Published2021-10-01 09:00:00.000000132,142,180,182,1839,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 189fc82ffa6-a8b6-44ae-b222-51778f84e1c4Double Entry Transactions PerformancePerform double entry transactions and confirms accounts are in balance.1798Published2021-10-01 09:00:00.000000132,180,182,18345,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1903270a66e-7763-442f-bae3-ddf5c8aba8e1Reports to StakeholdersProvide reports to stakeholders using accounting software and core systems.1798Published2021-10-01 09:00:00.00000091,132,133,134,135,143,147,148,165,166,180,182,18345,47,49,465,559,639,642,644,645,646,647 - 19101a10d41-bbe6-413b-9b45-b9eac7bbc7b6Payroll ProcessingRun payroll processing.1798Published2021-10-01 09:00:00.000000132,142,180,182,1839,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 1924a28c05f-e91c-4923-9782-1bb9b6981ad8Strategic Financial Decision RecommendationsApply insights to recommend strategic financial decisions and prepare financial reports for U.S. Securities and Exchange Commission (SEC) filings.1798Published2021-10-01 09:00:00.000000132,133,142,180,182,1839,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 193d30c8a27-93ea-420c-89a1-e1d0497ff014General Ledger Codes AssignmentAssign unique general ledger codes to each account within an accounting system.1918Published2021-10-01 09:00:00.000000132,142,143,147,192,193,194,195,19635,45,47,48,49,50,52,464,465,559,626,639,642,643,644,645,646,647,648,651 - 19495851275-eb69-4419-957a-2e1ca586350dDesign Features DevelopmentDevelop design features for the business accounting system to support business objectives.1918Published2021-10-01 09:00:00.000000132,133,192,1969,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 1952c1c5d29-ffe5-439e-97b8-70e8a818fca8Financial Statement GenerationGenerate financial statements for submission to regulatory agencies.1918Published2021-10-01 09:00:00.000000132,142,143,147,192,193,194,195,19635,45,47,48,49,50,52,464,465,559,626,639,642,643,644,645,646,647,648,651 - 19674c06473-35f9-4002-91ea-990377bb7baaBasic Accounting Process IdentificationIdentify basic accounting processes and systems within a structured environment to meet a limited need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 1971f7b45a1-8827-4c2c-990a-c5e51fe97a1dFunction ImplementationImplement customizable general business accounting functions into an integrated management information system to increase efficiency of the enterprise accounting system.1918Published2021-10-01 09:00:00.000000132,133,192,1969,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 198e9737bcd-0dcc-48af-a67c-9a06c7890c2bAccounting Systems MonitoringMonitor accounting systems to ensure compliance with organizational and federal guidelines.1918Published2021-10-01 09:00:00.000000132,134,192,1969,32,38,43,45,47,48,50,52,63,97,108,462,464,465,467,473,474,558,559,560,562,592,620,621,622,632,637,639,642,643,648,651,672,732,753,1461,1508,1509,1510,1528,1533,1543,1544,1549,1552,1588,1685,1712,2497,2498,2507 - 199524de3d9-5529-4bb3-aa7d-d9229a3b34adFinancial Data UploadingUpload financial data into accounting systems to generate monthly reports.1918Published2021-10-01 09:00:00.000000132,142,143,147,192,193,194,195,19635,45,47,48,49,50,52,464,465,559,626,639,642,643,644,645,646,647,648,651 - 20057c3889f-53a5-48ca-b02c-ccf9b50a6481Advanced Accounting Process ApplicationApply advanced accounting processes and systems within a broad environment to meet an organizational need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 2018056a96e-9136-401e-8b07-7330e84071e7Appropriate Accounting Process DeploymentDeploy appropriate accounting processes and systems within a limited environment to meet a routine need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 202af2b9424-cdf2-4a1f-a8f8-1281eb477d5eComplex Accounting Process ExecutionExecute complex accounting processes and systems within a wide environment to meet an organizational need.1918Published2021-10-01 09:00:00.000000132,134,192,19645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 90bb6a57c6-0779-46c7-b64a-0f6bb7827e70Determine Acceptance Testing DiscrepanciesDetermine if there are discrepancies between original software specifications and final acceptance testing scenarios.898Published2021-10-01 09:00:00.00000090,90,92,92,107,10754,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493,54,57,58,59,466,560,654,659,664,665,668,2487,2488,2489,2490,2491,2492,2493 - 9473ec441f-7c07-42d2-98c8-c8461e7f7c38User Experience Acceptance Test DesignDesign alterations to user experience components to meet acceptance testing criteria.898Published2021-10-01 09:00:00.00000090,90,92,92,110,110,111,11158,466,560,667,2494,58,466,560,667,2494 - 10378d61a82-8302-488c-9c3f-bf01d88e5ff9Network Router Security MonitoringMonitor network routers for security issues.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,124,12456,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 104f5b83170-bff2-4bff-93eb-660a2a9f6653Network Routers Security ConfigurationConfigure security on network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,123,123,125,12556,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 105b749ad2f-465a-41a3-92be-ba7072ce09b2Router Network Traffic ConfigurationConfigure network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,119,122,122,122,125,125,125,126,126,12656,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 105b749ad2f-465a-41a3-92be-ba7072ce09b2Router Network Traffic ConfigurationConfigure network routers for traffic between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,119,122,122,122,125,125,125,126,126,12656,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 106a3fe184d-921a-45f6-a384-308ca77b4498Network Connection DesignDesign a network connection between a core network and an internet service provider.1188Published2021-10-01 09:00:00.000000119,119,122,122,127,127,128,12856,57,466,560,657,659,662,2489,2490,2495,2496,56,57,466,560,657,659,662,2489,2490,2495,2496 - 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 10750b472d9-9d08-43c2-b6ba-8460bf2ac309Gap AnalysisAnalyze current processes and systems for gap identification.1298Published2021-10-01 09:00:00.000000130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,13645,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497,45,47,48,50,52,465,559,639,642,643,648,651,1540,1543,1544,1549,1552,2497 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 - 46a02ac8d-2e00-4fac-8fde-1f8237bdd769Large-Scale Web Application BuildBuild large-scale web applications using the .NET Framework with minimum coding.18Published2021-10-01 09:00:00.0000002,2,7,7,9,955,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 - 55cef80ee-5799-4f5c-89e5-8e4908419a50Service-Oriented Application BuildBuild service-oriented applications using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,7,7,10,1055,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 - 670b1fe1b-ecf1-4ca8-88ee-311d4d93ca67Application Domain CreationCreate application domains and assemblies using attributes, formatting and parsing base types, collections, events and exceptions, files and data streams, and generics.18Published2021-10-01 09:00:00.0000002,2,3,3,7,755,58,466,560,656,663,664,665,666,667,55,58,466,560,656,663,664,665,666,667 - 70a79c4b2-a715-4596-8211-b57e7e9e791aWindows-Based Application CreationCreate Windows-based applications using the .NET framework.18Published2021-10-01 09:00:00.0000002,2,7,7,11,1155,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 - 8c396acc6-9f88-484f-935d-8dbf9488c428Geometric Primitive Shape CombinationCombine geometric primitive shapes into digital 3D representations of a component of an object.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 - 9d59223d2-7a38-4146-8f4e-f226262bc2afGraphical Representation CreationCreate a 3D graphical representation of a physical object using specialized software.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 - 10ca32343a-1df3-4cb3-aa90-5dd6290ab248Layered Component IdentificationIdentify the layered components of a physical object that make up the complete digital three-dimensional (3D) rendering.128Published2021-10-01 09:00:00.00000013,13,14,14,15,15,16,16,17,17,18,18,19,1983,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466,83,469,561,696,1626,1627,1628,1629,1630,1631,1632,1633,1634,2464,2465,2466 - 117c9aff0f-0f53-4f92-b867-afe080da54a9System DesignDesign systems that facilitate trust and improved performance.208Published2021-10-01 09:00:00.00000021,21,22,2236,464,559,627,1521,36,464,559,627,1521 - 12c9eb1acd-c295-4e21-bcb4-e5574466575fTool ImplementationCreate accessible instructional documents using the tools within the document program.238Published2021-10-01 09:00:00.00000024,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,37,37143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469,143,146,148,483,484,565,843,846,851,1808,1813,2467,2468,2469 - - diff --git a/api/src/test/resources/mock-data.xml b/api/src/test/resources/mock-data.xml index 76fc4221a..a821a5612 100644 --- a/api/src/test/resources/mock-data.xml +++ b/api/src/test/resources/mock-data.xml @@ -632,13 +632,14 @@ 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 - 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778 - 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 - 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 - 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 - 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 - 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538 - 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548 + 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778 + 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 + 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 + 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 + 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 + 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538 + 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548 + 1975b5c26-9506-4e73-b4b2-83f4a838529dMy WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 From b0a7b7faf7730cade1a4217c8e45894eae620bf9 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:38:43 -0600 Subject: [PATCH 045/150] Download as CSV visibility & test - Add test workspace empty. - Download CSV is visible only when has RSDs. --- ui/src/app/my-workspace/my-workspace.component.spec.ts | 6 ++++++ ui/src/app/my-workspace/my-workspace.component.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index c0be61ef3..e4ffdd98a 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -97,4 +97,10 @@ describe("MyWorkspaceComponent", () => { expect(component.confirmButtonText).toBe("reset My Workspace") }) + it("workspace is not empty", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) + expect(component["workspaceEmpty"]()).toBeFalse() + }) + }) diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 12128ff96..e68bc54fc 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -54,7 +54,7 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O label: "Download as CSV", icon: this.downloadIcon, callback: () => this.generateCsv(this.collection?.name ?? ""), - visible: () => true + visible: () => !this.workspaceEmpty() }), new TableActionDefinition({ label: "Convert to Collection", From f720714a372c2ccb7b367f314a77f0cb806c5d44 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:53:17 -0600 Subject: [PATCH 046/150] Hide collection label --- .../public-collection-detail-card.component.html | 2 +- .../public-collection-detail-card.component.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html index 14a0f5d19..f5951c12a 100644 --- a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html +++ b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.html @@ -1,6 +1,6 @@
    - +

    {{collectionName}}

    diff --git a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.ts b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.ts index ba2f98bcf..d146eae20 100644 --- a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.ts +++ b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.ts @@ -54,4 +54,8 @@ export class PublicCollectionDetailCardComponent implements OnInit { get displayStatus(): boolean { return this.collection?.status !== PublishStatus.Workspace } + + get displayLabel(): boolean { + return this.collection?.status !== PublishStatus.Workspace + } } From a70777bf119194a39d60f7971fbfa1a92b93ac87 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:57:04 -0600 Subject: [PATCH 047/150] Hide audit log - Audit log is not visible on workspace. --- ui/src/app/collection/detail/manage-collection.component.html | 2 +- ui/src/app/collection/detail/manage-collection.component.ts | 1 + ui/src/app/my-workspace/my-workspace.component.ts | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/src/app/collection/detail/manage-collection.component.html b/ui/src/app/collection/detail/manage-collection.component.html index 4eb43213e..d1d799cdc 100644 --- a/ui/src/app/collection/detail/manage-collection.component.html +++ b/ui/src/app/collection/detail/manage-collection.component.html @@ -81,7 +81,7 @@ > -
    +
    selectAllChecked = false + showLog = true collapseAuditLog = new Subject() diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index e68bc54fc..11ed3f248 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -16,6 +16,8 @@ import {ApiCollectionUpdate} from "../collection/ApiCollection" }) export class MyWorkspaceComponent extends ManageCollectionComponent implements OnInit { + showLog = false + constructor( protected router: Router, protected richSkillService: RichSkillService, From 92f9c820a05006fa1befd4864e322e50de86d02e Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:57:29 -0600 Subject: [PATCH 048/150] Convert publish status enum to lower case. --- ui/src/app/PublishStatus.ts | 10 +++++----- .../app/collection/service/collection.service.spec.ts | 2 +- .../app/richskill/service/rich-skill.service.spec.ts | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ui/src/app/PublishStatus.ts b/ui/src/app/PublishStatus.ts index d44ac97c8..de930f620 100644 --- a/ui/src/app/PublishStatus.ts +++ b/ui/src/app/PublishStatus.ts @@ -1,11 +1,11 @@ import {ApiCollectionSummary, ApiSkillSummary} from "./richskill/ApiSkillSummary"; export enum PublishStatus { - Unarchived = "Unarchived", - Published = "Published", - Archived = "Archived", - Deleted = "Deleted", - Draft = "Draft", + Unarchived = "unarchived", + Published = "published", + Archived = "archived", + Deleted = "deleted", + Draft = "draft", Workspace = "workspace" } diff --git a/ui/src/app/collection/service/collection.service.spec.ts b/ui/src/app/collection/service/collection.service.spec.ts index 8185f552f..47cd2ce93 100644 --- a/ui/src/app/collection/service/collection.service.spec.ts +++ b/ui/src/app/collection/service/collection.service.spec.ts @@ -81,7 +81,7 @@ describe("CollectionService", () => { // Arrange RouterData.commands = [] AuthServiceData.isDown = false - const path = "api/collections?sort=name.asc&status=Draft&size=3&from=0" + const path = "api/collections?sort=name.asc&status=draft&size=3&from=0" const testData: PaginatedCollections = createMockPaginatedCollections(3, 10) const statuses = new Set([ PublishStatus.Draft ]) diff --git a/ui/src/app/richskill/service/rich-skill.service.spec.ts b/ui/src/app/richskill/service/rich-skill.service.spec.ts index 5cf52bebf..575bd1e98 100644 --- a/ui/src/app/richskill/service/rich-skill.service.spec.ts +++ b/ui/src/app/richskill/service/rich-skill.service.spec.ts @@ -80,7 +80,7 @@ describe("RichSkillService", () => { // Arrange RouterData.commands = [] AuthServiceData.isDown = false - const path = "api/skills?sort=name.asc&status=Draft&size=3&from=0" + const path = "api/skills?sort=name.asc&status=draft&size=3&from=0" const testData: PaginatedSkills = createMockPaginatedSkills(3, 10) const statuses = new Set([ PublishStatus.Draft ]) @@ -301,7 +301,7 @@ describe("RichSkillService", () => { }) const req = httpTestingController.expectOne(AppConfig.settings.baseApiUrl + "/" + path + - "?sort=skill.asc&status=Published&status=Draft&size=5&from=1") + "?sort=skill.asc&status=published&status=draft&size=5&from=1") expect(req.request.method).toEqual("POST") req.flush(testData.skills, { headers: { "x-total-count": "" + testData.totalCount} @@ -381,7 +381,7 @@ describe("RichSkillService", () => { /* Service call will make 2 requests: the requested action + the async task result */ /* Setup for request 1 */ const req1 = httpTestingController.expectOne(AppConfig.settings.baseApiUrl + "/" + path1 + - "?newStatus=Published") + "?newStatus=published") expect(req1.request.method).toEqual("POST") req1.flush(taskResult) From aa329266783aec2ba2c0febf9a9c60f03afbe259 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:08:06 -0600 Subject: [PATCH 049/150] Curator can use workspace --- ui/src/app/app-routing.module.ts | 8 ++++ .../collection-skill-search.component.ts | 2 +- .../my-workspace/my-workspace.component.ts | 5 ++ .../richskill/list/skills-list.component.ts | 48 +++++++++++-------- .../action-bar-item.component.html | 2 +- .../action-bar-item.components.scss | 8 ++++ 6 files changed, 52 insertions(+), 21 deletions(-) diff --git a/ui/src/app/app-routing.module.ts b/ui/src/app/app-routing.module.ts index d540b9b3d..9a1dcd096 100644 --- a/ui/src/app/app-routing.module.ts +++ b/ui/src/app/app-routing.module.ts @@ -150,6 +150,14 @@ const routes: Routes = [ component: MyWorkspaceComponent, canActivate: [AuthGuard] }, + { + path: "my-workspace/:uuid/add-skills", + component: CollectionSkillSearchComponent, + canActivate: [AuthGuard], + data: { + roles: ActionByRoles.get(ButtonAction.MyWorkspace) + } + }, /* PUBLIC VIEWS */ {path: "skills/:uuid", component: RichSkillPublicComponent}, {path: "collections/:uuid", component: CollectionPublicComponent}, diff --git a/ui/src/app/collection/collection-skill-search.component.ts b/ui/src/app/collection/collection-skill-search.component.ts index f41b69afd..d4b28c17b 100644 --- a/ui/src/app/collection/collection-skill-search.component.ts +++ b/ui/src/app/collection/collection-skill-search.component.ts @@ -110,7 +110,7 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen icon: "collection", primary: true, callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), - visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) + visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) || this.addToWorkspaceVisible() }) ] } diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 11ed3f248..84ef50f4d 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -101,4 +101,9 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O }) } + addSkillsAction(): void { + this.router.navigate([`/my-workspace/${this.collection?.uuid}/add-skills`]) + } + + } diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 05b76762b..a6519727f 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -1,19 +1,19 @@ import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../service/rich-skill-search.service" -import {ApiSkillSummary} from "../ApiSkillSummary"; -import {checkArchived, determineFilters, PublishStatus} from "../../PublishStatus"; -import {TableActionDefinition} from "../../table/skills-library-table/has-action-definitions"; -import {Component, ElementRef, ViewChild} from "@angular/core"; -import {Observable} from "rxjs"; -import {ApiBatchResult} from "../ApiBatchResult"; -import {RichSkillService} from "../service/rich-skill.service"; -import {ToastService} from "../../toast/toast.service"; -import {ApiSortOrder} from "../ApiSkill"; -import {Router} from "@angular/router"; -import {QuickLinksHelper} from "../../core/quick-links-helper"; -import {ExtrasSelectedSkillsState} from "../../collection/add-skills-collection.component"; -import {TableActionBarComponent} from "../../table/skills-library-table/table-action-bar.component"; -import {AuthService} from "../../auth/auth-service"; -import {ButtonAction} from "../../auth/auth-roles"; +import {ApiSkillSummary} from "../ApiSkillSummary" +import {checkArchived, determineFilters, PublishStatus} from "../../PublishStatus" +import {TableActionDefinition} from "../../table/skills-library-table/has-action-definitions" +import {Component, ElementRef, ViewChild} from "@angular/core" +import {Observable} from "rxjs" +import {ApiBatchResult} from "../ApiBatchResult" +import {RichSkillService} from "../service/rich-skill.service" +import {ToastService} from "../../toast/toast.service" +import {ApiSortOrder} from "../ApiSkill" +import {Router} from "@angular/router" +import {QuickLinksHelper} from "../../core/quick-links-helper" +import {ExtrasSelectedSkillsState} from "../../collection/add-skills-collection.component" +import {TableActionBarComponent} from "../../table/skills-library-table/table-action-bar.component" +import {AuthService} from "../../auth/auth-service" +import {ButtonAction} from "../../auth/auth-roles" import {CollectionService} from "../../collection/service/collection.service" import {ApiCollection} from "../../collection/ApiCollection" import {CollectionPipe} from "../../pipes" @@ -150,8 +150,12 @@ export class SkillsListComponent extends QuickLinksHelper { return false } + addToVisible(): boolean { + return (this.selectedSkills?.length ?? 0) > 0 + } + addToCollectionVisible(skill?: ApiSkillSummary): boolean { - return ((this.selectedSkills?.length ?? 0) > 0) && this.authService.isEnabledByRoles(ButtonAction.CollectionSkillsUpdate) + return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.CollectionSkillsUpdate) } handleFiltersChanged(newFilters: Set): void { @@ -254,15 +258,17 @@ export class SkillsListComponent extends QuickLinksHelper { label: "Add to", icon: "add", primary: true, - visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill), + visible: (skill?: ApiSkillSummary) => this.addToVisible(), menu: [ { label: "Add to Collection", callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), + visible: () => this.addToCollectionVisible() }, { label: "Add to Workspace", - callback: () => this.handleClickAddToWorkspace() + callback: () => this.handleClickAddToWorkspace(), + visible: () => this.addToWorkspaceVisible() } ] })) @@ -272,7 +278,7 @@ export class SkillsListComponent extends QuickLinksHelper { icon: "dismiss", primary: true, callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickRemoveCollection(action, skill), - visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) + visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) || this.addToWorkspaceVisible() })) } @@ -280,6 +286,10 @@ export class SkillsListComponent extends QuickLinksHelper { } + protected addToWorkspaceVisible(): boolean { + return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.MyWorkspace) && this.collection?.status === PublishStatus.Workspace + } + protected handleClickExportSearch(): void { } diff --git a/ui/src/app/table/skills-library-table/action-bar-item.component.html b/ui/src/app/table/skills-library-table/action-bar-item.component.html index a5df37063..18342f3ac 100644 --- a/ui/src/app/table/skills-library-table/action-bar-item.component.html +++ b/ui/src/app/table/skills-library-table/action-bar-item.component.html @@ -17,7 +17,7 @@
    -
    diff --git a/ui/src/app/table/skills-library-table/action-bar-item.components.scss b/ui/src/app/table/skills-library-table/action-bar-item.components.scss index 2e6e46569..00c334d83 100644 --- a/ui/src/app/table/skills-library-table/action-bar-item.components.scss +++ b/ui/src/app/table/skills-library-table/action-bar-item.components.scss @@ -38,6 +38,7 @@ } .dropup-item { + width: 100%; color: black; padding-left: 10%; padding-top: 5%; @@ -48,6 +49,13 @@ text-decoration: underline; } +.dropup-item:disabled { + background-color: #cccccc; + color: #666666; + text-decoration: none; + cursor:not-allowed +} + hr { border: 0.5px solid gray; margin: 1px 5px; From da5d6d1ceba8f2aabafa92713ccfea13f0cd0efc Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 9 Feb 2023 16:43:39 -0600 Subject: [PATCH 050/150] Add convert to collection component --- ui/src/app/app-routing.module.ts | 9 ++++ ui/src/app/app.module.ts | 2 + .../collection-skill-search.component.ts | 2 +- .../collection-form.component.ts | 12 ++--- .../convert-to-collection.component.spec.ts | 25 ++++++++++ .../convert-to-collection.component.ts | 48 +++++++++++++++++++ .../my-workspace/my-workspace.component.ts | 19 ++++---- .../richskill/list/skills-list.component.ts | 2 +- 8 files changed, 102 insertions(+), 17 deletions(-) create mode 100644 ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts create mode 100644 ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.ts diff --git a/ui/src/app/app-routing.module.ts b/ui/src/app/app-routing.module.ts index 9a1dcd096..ca963e124 100644 --- a/ui/src/app/app-routing.module.ts +++ b/ui/src/app/app-routing.module.ts @@ -22,6 +22,7 @@ import {CollectionSkillSearchComponent} from "./collection/collection-skill-sear import {BatchImportComponent} from "./richskill/import/batch-import.component" import { ActionByRoles, ButtonAction } from "./auth/auth-roles" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" +import {ConvertToCollectionComponent} from "./my-workspace/convert-to-collection/convert-to-collection.component" const routes: Routes = [ @@ -158,6 +159,14 @@ const routes: Routes = [ roles: ActionByRoles.get(ButtonAction.MyWorkspace) } }, + { + path: "my-workspace/convert-to-collection", + component: ConvertToCollectionComponent, + canActivate: [AuthGuard], + data: { + roles: ActionByRoles.get(ButtonAction.MyWorkspace) + } + }, /* PUBLIC VIEWS */ {path: "skills/:uuid", component: RichSkillPublicComponent}, {path: "collections/:uuid", component: CollectionPublicComponent}, diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 4493868c5..d02fc5c15 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -99,6 +99,7 @@ import {LabelWithSelectComponent} from "./table/skills-library-table/label-with- import {LibraryExportComponent} from "./navigation/libraryexport.component" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" import {CollectionPipe} from "./pipes" +import { ConvertToCollectionComponent } from "./my-workspace/convert-to-collection/convert-to-collection.component" export function initializeApp( appConfig: AppConfig, @@ -211,6 +212,7 @@ export function initializeApp( LabelWithSelectComponent, MyWorkspaceComponent, CollectionPipe, + ConvertToCollectionComponent, ], imports: [ NgIdleKeepaliveModule.forRoot(), diff --git a/ui/src/app/collection/collection-skill-search.component.ts b/ui/src/app/collection/collection-skill-search.component.ts index d4b28c17b..f41b69afd 100644 --- a/ui/src/app/collection/collection-skill-search.component.ts +++ b/ui/src/app/collection/collection-skill-search.component.ts @@ -110,7 +110,7 @@ export class CollectionSkillSearchComponent extends SkillsListComponent implemen icon: "collection", primary: true, callback: (action: TableActionDefinition, skill?: ApiSkillSummary) => this.handleClickAddCollection(action, skill), - visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) || this.addToWorkspaceVisible() + visible: (skill?: ApiSkillSummary) => this.addToCollectionVisible(skill) }) ] } diff --git a/ui/src/app/collection/create-collection/collection-form.component.ts b/ui/src/app/collection/create-collection/collection-form.component.ts index 43c1ddf3a..25d3c802e 100644 --- a/ui/src/app/collection/create-collection/collection-form.component.ts +++ b/ui/src/app/collection/create-collection/collection-form.component.ts @@ -33,12 +33,12 @@ export class CollectionFormComponent extends Whitelabelled implements OnInit, Ha } constructor( - private collectionService: CollectionService, - private loc: Location, - private router: Router, - private route: ActivatedRoute, - private toastService: ToastService, - private titleService: Title + protected collectionService: CollectionService, + protected loc: Location, + protected router: Router, + protected route: ActivatedRoute, + protected toastService: ToastService, + protected titleService: Title ) { super() } diff --git a/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts b/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts new file mode 100644 index 000000000..e6b7f1081 --- /dev/null +++ b/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing" + +import { ConvertToCollectionComponent } from "./convert-to-collection.component" + +describe("ConvertToCollectionComponent", () => { + let component: ConvertToCollectionComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ConvertToCollectionComponent ] + }) + .compileComponents() + }) + + beforeEach(() => { + fixture = TestBed.createComponent(ConvertToCollectionComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it("should create", () => { + expect(component).toBeTruthy() + }) +}) diff --git a/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.ts b/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.ts new file mode 100644 index 000000000..e254cf8af --- /dev/null +++ b/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.ts @@ -0,0 +1,48 @@ +import {Component, OnInit} from "@angular/core" +import {CollectionFormComponent} from "../../collection/create-collection/collection-form.component" +import {CollectionService} from "../../collection/service/collection.service" +import {Location} from "@angular/common" +import {ActivatedRoute, Router} from "@angular/router" +import {ToastService} from "../../toast/toast.service" +import {Title} from "@angular/platform-browser" +import {ICollectionUpdate} from "../../collection/ApiCollection" +import {WORKSPACE_COLLECTIONS_UUIDS} from "../my-workspace.component" + +@Component({ + selector: "app-convert-to-collection", + templateUrl: "../../collection/create-collection/collection-form.component.html", +}) +export class ConvertToCollectionComponent extends CollectionFormComponent implements OnInit { + + constructor( + protected collectionService: CollectionService, + protected loc: Location, + protected router: Router, + protected route: ActivatedRoute, + protected toastService: ToastService, + protected titleService: Title + ) { + super(collectionService, loc, router, route, toastService, titleService) + } + + updateObject(): ICollectionUpdate { + const formValues = this.collectionForm.value + const collectionsUuids = localStorage.getItem(WORKSPACE_COLLECTIONS_UUIDS) + return { + name: formValues.collectionName, + author: formValues.author, + skills: {add: JSON.parse(collectionsUuids ?? "")} + } + } + + + onSubmit(): void { + const updateObject = this.updateObject() + this.collectionService.createCollection(updateObject).subscribe(collection => { + this.router.navigate([`/collections/${collection.uuid}/manage`]).then(() => { + localStorage.removeItem(WORKSPACE_COLLECTIONS_UUIDS) + }) + }) + } + +} diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 84ef50f4d..59428e03b 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -8,7 +8,9 @@ import {Title} from "@angular/platform-browser" import {AuthService} from "../auth/auth-service" import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions" import {ApiSearch} from "../richskill/service/rich-skill-search.service" -import {ApiCollectionUpdate} from "../collection/ApiCollection" +import {ButtonAction} from "../auth/auth-roles" + +export const WORKSPACE_COLLECTIONS_UUIDS = "workspace-collections-uuids" @Component({ selector: "app-my-workspace", @@ -91,19 +93,18 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O } private convertToCollectionAction(): void { - const updateObject = new ApiCollectionUpdate({ - name: this.collection?.name, - author: this.collection?.author, - skills: {add: this.collection?.skills.map(s => (s as any).uuid)} - }) - this.collectionService.createCollection(updateObject).subscribe(newCollection => { - this.router.navigate(["/collections/" + newCollection.uuid + "/manage"]) - }) + const uuids = this.collection?.skills.map(s => (s as any).uuid) + localStorage.setItem(WORKSPACE_COLLECTIONS_UUIDS, JSON.stringify(uuids)) + this.router.navigate(["/my-workspace/convert-to-collection"]) } addSkillsAction(): void { this.router.navigate([`/my-workspace/${this.collection?.uuid}/add-skills`]) } + addToCollectionVisible(): boolean { + return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.MyWorkspace) + } + } diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index a6519727f..a25d37272 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -287,7 +287,7 @@ export class SkillsListComponent extends QuickLinksHelper { } protected addToWorkspaceVisible(): boolean { - return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.MyWorkspace) && this.collection?.status === PublishStatus.Workspace + return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.MyWorkspace) } protected handleClickExportSearch(): void { From 5f60c3757d58d95de3f9ad43f91638ecfb26e1d5 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 9 Feb 2023 17:52:18 -0600 Subject: [PATCH 051/150] Add tests workspace - Add tests in convert to collection. - Add tests in my workspace. --- .../convert-to-collection.component.spec.ts | 63 +++++++++++++++++-- .../my-workspace.component.spec.ts | 24 +++++-- 2 files changed, 78 insertions(+), 9 deletions(-) diff --git a/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts b/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts index e6b7f1081..a9a4aaddd 100644 --- a/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts +++ b/ui/src/app/my-workspace/convert-to-collection/convert-to-collection.component.spec.ts @@ -1,16 +1,50 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing" +import {ComponentFixture, TestBed} from "@angular/core/testing" -import { ConvertToCollectionComponent } from "./convert-to-collection.component" +import {ConvertToCollectionComponent} from "./convert-to-collection.component" +import {RouterTestingModule} from "@angular/router/testing" +import {HttpClientTestingModule} from "@angular/common/http/testing" +import {AppConfig} from "../../app.config" +import {Location} from "@angular/common" +import {Title} from "@angular/platform-browser" +import {ToastService} from "../../toast/toast.service" +import {EnvironmentService} from "../../core/environment.service" +import {CollectionServiceStub, EnvironmentServiceStub} from "../../../../test/resource/mock-stubs" +import {CollectionService} from "../../collection/service/collection.service" +import {ActivatedRoute, Router} from "@angular/router" +import {ActivatedRouteStubSpec} from "../../../../test/util/activated-route-stub.spec" describe("ConvertToCollectionComponent", () => { let component: ConvertToCollectionComponent let fixture: ComponentFixture + let activatedRoute: ActivatedRouteStubSpec + + activatedRoute = new ActivatedRouteStubSpec() + activatedRoute.setParams({ uuid: "uuid1" }) beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ ConvertToCollectionComponent ] - }) - .compileComponents() + declarations: [ConvertToCollectionComponent], + imports: [ + RouterTestingModule, + HttpClientTestingModule + ], + providers: [ + AppConfig, + Location, + Title, + ToastService, + {provide: EnvironmentService, useClass: EnvironmentServiceStub}, + {provide: CollectionService, useClass: CollectionServiceStub}, + { provide: ActivatedRoute, useValue: activatedRoute }, + ] + }).compileComponents() + + const appConfig = TestBed.inject(AppConfig) + AppConfig.settings = appConfig.defaultConfig() + + const environmentService = TestBed.inject(EnvironmentService) + environmentService.environment.editableAuthor = true + AppConfig.settings.editableAuthor = true // Doubly sure }) beforeEach(() => { @@ -22,4 +56,23 @@ describe("ConvertToCollectionComponent", () => { it("should create", () => { expect(component).toBeTruthy() }) + + it("on submit should call create", () => { + const spyUpdateObject = spyOn(component, "updateObject") + const router = TestBed.inject(Router) + const spyRouter = spyOn(router, "navigate").and.resolveTo(true) + const service = TestBed.inject(CollectionService) + const spyService = spyOn(service, "createCollection").and.callThrough() + component.onSubmit() + expect(spyUpdateObject).toHaveBeenCalled() + expect(spyService).toHaveBeenCalled() + expect(spyRouter).toHaveBeenCalled() + }) + + it("update object should has skills", () => { + const spyLocalStorage = spyOn(localStorage, "getItem").and.returnValue("[423423, 234234]") + const updateObject = component.updateObject() + expect(spyLocalStorage).toHaveBeenCalled() + expect(updateObject.skills).toBeTruthy() + }) }) diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index e4ffdd98a..33ad4d74d 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -13,7 +13,7 @@ import {EnvironmentService} from "../core/environment.service" import {CollectionService} from "../collection/service/collection.service" import {Router} from "@angular/router" import {ManageCollectionComponent} from "../collection/detail/manage-collection.component" -import {createMockCollection} from "../../../test/resource/mock-data" +import {createMockCollection, createMockSkillSummary} from "../../../test/resource/mock-data" import {PublishStatus} from "../PublishStatus" describe("MyWorkspaceComponent", () => { @@ -26,7 +26,7 @@ describe("MyWorkspaceComponent", () => { imports: [ RouterTestingModule.withRoutes([ { - path: "collections/uuid1/manage", + path: "my-workspace/uuid1/add-skills", component: ManageCollectionComponent } ]), @@ -78,10 +78,10 @@ describe("MyWorkspaceComponent", () => { it("convert to collection action", () => { const router = TestBed.inject(Router) - const spy = spyOn(collectionService, "createCollection").and.callThrough() const spyNavigate = spyOn(router, "navigate").and.callThrough() + const spyLocalStorage = spyOn(localStorage, "setItem").and.callThrough() component["convertToCollectionAction"]() - expect(spy).toHaveBeenCalled() + expect(spyLocalStorage).toHaveBeenCalled() expect(spyNavigate).toHaveBeenCalled() }) @@ -103,4 +103,20 @@ describe("MyWorkspaceComponent", () => { expect(component["workspaceEmpty"]()).toBeFalse() }) + it("router should navigate correctly", () => { + const router = TestBed.inject(Router) + const spy = spyOn(router, "navigate").and.resolveTo(true) + component.addSkillsAction() + expect(spy).toHaveBeenCalledWith(["/my-workspace/uuid1/add-skills"]) + }) + + it("add to collection should not be visible", () => { + expect(component.addToCollectionVisible()).toBeFalse() + }) + + it("add to collection should be visible", () => { + component.selectedSkills = [createMockSkillSummary()] + expect(component.addToCollectionVisible()).toBeTrue() + }) + }) From d89309fba60ca1db51139d74bc81b0c2b58360e7 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 10 Feb 2023 08:48:56 -0600 Subject: [PATCH 052/150] Correcting mock xml record --- api/src/test/resources/mock-data.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/resources/mock-data.xml b/api/src/test/resources/mock-data.xml index a821a5612..c9cff8431 100644 --- a/api/src/test/resources/mock-data.xml +++ b/api/src/test/resources/mock-data.xml @@ -639,7 +639,7 @@ 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548 - 1975b5c26-9506-4e73-b4b2-83f4a838529dMy WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com + 824edf6ee-a951-11ed-afa1-0242ac120002My WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 From 20bb1434b0fe85ef1805340644e4a0952376584a Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 10 Feb 2023 09:16:12 -0600 Subject: [PATCH 053/150] testing remote fix for mock xml record --- api/src/test/resources/mock-data.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/src/test/resources/mock-data.xml b/api/src/test/resources/mock-data.xml index c9cff8431..314ae577f 100644 --- a/api/src/test/resources/mock-data.xml +++ b/api/src/test/resources/mock-data.xml @@ -632,14 +632,13 @@ 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 - 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778 + 124edf6ee-a951-11ed-afa1-0242ac120002My WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548 - 824edf6ee-a951-11ed-afa1-0242ac120002My WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 From c353de331543b60c26a110c92919db6d5c42fd5b Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 10 Feb 2023 09:46:24 -0600 Subject: [PATCH 054/150] testing remote fix for mock xml record --- api/src/test/resources/mock-data.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/resources/mock-data.xml b/api/src/test/resources/mock-data.xml index 314ae577f..71aec0add 100644 --- a/api/src/test/resources/mock-data.xml +++ b/api/src/test/resources/mock-data.xml @@ -632,7 +632,7 @@ 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 - 124edf6ee-a951-11ed-afa1-0242ac120002My WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com + 124edf6ee-a951-11ed-afa1-0242ac120002My_WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 From 281185ffd209fb0f09312b240cfabee5a4695ec1 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 10 Feb 2023 10:15:58 -0600 Subject: [PATCH 055/150] testing remote fix for mock xml record --- api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt | 2 +- api/src/test/resources/mock-data.xml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt index d23ae65e9..1bb9bb40e 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/mockdata/MockData.kt @@ -41,7 +41,7 @@ class MockData { appConfig = createAppConfig() try { - val filename = "mock-data-v2.xml" + val filename = "mock-data.xml" val file = this::class.java.classLoader.getResource(filename) if (file == null) { log.error("Unable to open {}", filename) diff --git a/api/src/test/resources/mock-data.xml b/api/src/test/resources/mock-data.xml index 71aec0add..f1054d0b8 100644 --- a/api/src/test/resources/mock-data.xml +++ b/api/src/test/resources/mock-data.xml @@ -632,13 +632,14 @@ 1962021-06-14 14:44:20.6025612021-06-14 14:44:20.602561AlignmentAccounting Systems2021-06-14 14:44:20.602561 - 124edf6ee-a951-11ed-afa1-0242ac120002My_WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com + 1975b5c26-9506-4e73-b4b2-83f4a838529dPower_Skills_FrameworkPublished2021-10-01 09:00:00.00000050,64,53,63,55,61,5778 29124e022-0723-4bf3-8bec-0a271616b5eaSELPublished2021-10-01 09:00:00.00000050,64,63,61,57,55,5378 3afaa6b8a-680a-4642-add1-014f977c9ca721st_Century_SkillsPublished2021-10-01 09:00:00.00000055,57,61,53,63,64,5078 49903442f-ed1e-42d4-8d95-858a26204d500Published2021-10-01 09:00:00.00000050,167,168,55,61,53,5778 5f07b2276-4d1c-46cf-a971-746c214bc3bcHealth_Open_SkillsPublished2021-10-01 09:00:00.000000168,167,166,142,141,140,139,6688 63dc22c04-1aa2-4dea-9dfc-0f016573428aDEI_CollectionPublished2021-10-01 09:00:00.00000078,77,7538 72938a728-f6e2-41a1-8a3b-9a838a56d212CharacterPublished2021-10-01 09:00:00.00000078,77,76,7548 + 8e940e731-4a74-4c48-9264-a69ad978e609My WorkspaceWorkspace50,64,53,63,55,61,5778user@email.com 340b3546e-ca1f-4129-a07d-b0ab03dec1a2Data and Data Store AccessAccess data and data stores using the .NET Framework.18Published2021-10-01 09:00:00.0000002,2,3,3,4,4,5,5,6,6,7,755,58,59,466,560,656,663,664,665,666,667,668,55,58,59,466,560,656,663,664,665,666,667,668 From 9181cba4aec51f944806b9f58058a5c0673c1521 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:27:47 -0600 Subject: [PATCH 056/150] Update tests workspace --- ...c-collection-detail-card.component.spec.ts | 16 +++++++ .../manage-collection.component.spec.ts | 6 +++ .../my-workspace.component.spec.ts | 48 ++++++++++++++++++- .../list/skills-list.component.spec.ts | 31 +++++++----- 4 files changed, 87 insertions(+), 14 deletions(-) diff --git a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts index 1a3f1dcbf..43200ef4a 100644 --- a/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts +++ b/ui/src/app/collection/detail/collection-public/public-collection-detail-card.component.spec.ts @@ -7,6 +7,8 @@ import { RichSkillService } from "../../../richskill/service/rich-skill.service" import { ToastService } from "../../../toast/toast.service" import { PublicCollectionDetailCardComponent } from "./public-collection-detail-card.component" import {CollectionPipe} from "../../../pipes" +import {createMockCollection} from "../../../../../test/resource/mock-data" +import {PublishStatus} from "../../../PublishStatus" export function createComponent(T: Type): Promise { @@ -58,4 +60,18 @@ describe("PublicCollectionDetailCardComponent", () => { it("should be created", () => { expect(component).toBeTruthy() }) + + it("display status and display label should be false", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) + expect(component.displayStatus).toBeFalse() + expect(component.displayLabel).toBeFalse() + }) + + it("display status and label should be true", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Draft) + expect(component.displayStatus).toBeTrue() + expect(component.displayLabel).toBeTrue() + }) }) diff --git a/ui/src/app/collection/detail/manage-collection.component.spec.ts b/ui/src/app/collection/detail/manage-collection.component.spec.ts index 323cef7c8..aa00c9b3e 100644 --- a/ui/src/app/collection/detail/manage-collection.component.spec.ts +++ b/ui/src/app/collection/detail/manage-collection.component.spec.ts @@ -565,4 +565,10 @@ describe("ManageCollectionComponent", () => { component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) expect(component.confirmButtonText).toBe("delete collection") }) + + it("show log should be true", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Draft) + expect(component.showLog).toBeTrue() + }) }) diff --git a/ui/src/app/my-workspace/my-workspace.component.spec.ts b/ui/src/app/my-workspace/my-workspace.component.spec.ts index 33ad4d74d..083737a42 100644 --- a/ui/src/app/my-workspace/my-workspace.component.spec.ts +++ b/ui/src/app/my-workspace/my-workspace.component.spec.ts @@ -7,7 +7,7 @@ import {RichSkillService} from "../richskill/service/rich-skill.service" import {AuthServiceStub, CollectionServiceStub, EnvironmentServiceStub, RichSkillServiceStub} from "../../../test/resource/mock-stubs" import {HttpClientTestingModule} from "@angular/common/http/testing" import {AppConfig} from "../app.config" -import {Title} from "@angular/platform-browser" +import {By, Title} from "@angular/platform-browser" import {ToastService} from "../toast/toast.service" import {EnvironmentService} from "../core/environment.service" import {CollectionService} from "../collection/service/collection.service" @@ -15,6 +15,23 @@ import {Router} from "@angular/router" import {ManageCollectionComponent} from "../collection/detail/manage-collection.component" import {createMockCollection, createMockSkillSummary} from "../../../test/resource/mock-data" import {PublishStatus} from "../PublishStatus" +import {PublicCollectionDetailCardComponent} from "../collection/detail/collection-public/public-collection-detail-card.component" +import {VerticalActionBarComponent} from "../core/vertical-action-bar.component" +import {FilterControlsComponent} from "../table/filter-controls/filter-controls.component" +import {FilterChoiceComponent} from "../table/filter-controls/filter-choice.component" +import {TableActionBarComponent} from "../table/skills-library-table/table-action-bar.component" +import {ActionBarItemComponent} from "../table/skills-library-table/action-bar-item.component" +import {CommonModule} from "@angular/common" +import {ReactiveFormsModule} from "@angular/forms" +import {LoadingObservablesDirective} from "../loading/loading-observables.directive" +import {SkillTableComponent} from "../table/skills-library-table/skill-table.component" +import {PaginationComponent} from "../table/skills-library-table/pagination.component" +import {LabelWithSelectComponent} from "../table/skills-library-table/label-with-select.component" +import {AuditLogComponent} from "../richskill/detail/audit-log.component" +import {LabelWithFilterComponent} from "../table/skills-library-table/label-with-filter.component" +import {SkillListRowComponent} from "../richskill/list/skill-list-row.component" +import {StatusBarComponent} from "../core/status-bar.component" +import {DotsMenuComponent} from "../table/skills-library-table/dots-menu.component" describe("MyWorkspaceComponent", () => { let component: MyWorkspaceComponent @@ -31,8 +48,27 @@ describe("MyWorkspaceComponent", () => { } ]), HttpClientTestingModule, + CommonModule, + ReactiveFormsModule + ], + declarations: [ + MyWorkspaceComponent, + PublicCollectionDetailCardComponent, + VerticalActionBarComponent, + FilterControlsComponent, + FilterChoiceComponent, + TableActionBarComponent, + ActionBarItemComponent, + LoadingObservablesDirective, + SkillTableComponent, + PaginationComponent, + LabelWithSelectComponent, + LabelWithFilterComponent, + AuditLogComponent, + SkillListRowComponent, + StatusBarComponent, + DotsMenuComponent, ], - declarations: [MyWorkspaceComponent], providers: [ AppConfig, Title, @@ -119,4 +155,12 @@ describe("MyWorkspaceComponent", () => { expect(component.addToCollectionVisible()).toBeTrue() }) + it("show log should be false", () => { + const date = new Date() + component.collection = createMockCollection(date, date, date, date, PublishStatus.Workspace) + const auditLog = fixture.debugElement.query(By.css("app-audit-log")) + expect(component.showLog).toBeFalse() + expect(auditLog).toBeFalsy() + }) + }) diff --git a/ui/src/app/richskill/list/skills-list.component.spec.ts b/ui/src/app/richskill/list/skills-list.component.spec.ts index 1b35a8a80..ee361546f 100644 --- a/ui/src/app/richskill/list/skills-list.component.spec.ts +++ b/ui/src/app/richskill/list/skills-list.component.spec.ts @@ -1,19 +1,19 @@ // noinspection MagicNumberJS,LocalVariableNamingConventionJS -import { Component, ElementRef, Type } from "@angular/core" -import { async, ComponentFixture, TestBed } from "@angular/core/testing" -import { RouterTestingModule } from "@angular/router/testing" -import { createMockPaginatedSkills, createMockSkillSummary } from "../../../../test/resource/mock-data" +import {Component, ElementRef, Type} from "@angular/core" +import {async, ComponentFixture, TestBed} from "@angular/core/testing" +import {RouterTestingModule} from "@angular/router/testing" +import {createMockCollection, createMockPaginatedSkills, createMockSkillSummary} from "../../../../test/resource/mock-data" import {AuthServiceStub, CollectionServiceStub, RichSkillServiceStub} from "../../../../test/resource/mock-stubs" -import { PublishStatus } from "../../PublishStatus" -import { ToastService } from "../../toast/toast.service" -import { ApiSortOrder } from "../ApiSkill" -import { ApiSearch, PaginatedSkills } from "../service/rich-skill-search.service" -import { RichSkillService } from "../service/rich-skill.service" -import { SkillsListComponent } from "./skills-list.component" -import {AuthService} from "../../auth/auth-service"; +import {PublishStatus} from "../../PublishStatus" +import {ToastService} from "../../toast/toast.service" +import {ApiSortOrder} from "../ApiSkill" +import {ApiSearch, PaginatedSkills} from "../service/rich-skill-search.service" +import {RichSkillService} from "../service/rich-skill.service" +import {SkillsListComponent} from "./skills-list.component" +import {AuthService} from "../../auth/auth-service" import {CollectionService} from "../../collection/service/collection.service" -import {HttpClient, HttpClientModule, HttpHandler} from "@angular/common/http" +import {HttpClientModule} from "@angular/common/http" @Component({ @@ -490,4 +490,11 @@ describe("SkillsListComponent", () => { it("getSelectAllEnabled should be true", () => { expect(component.getSelectAllEnabled()).toBeTruthy() }) + + it("add to workspace should be visible", () => { + component.selectedSkills = [ + createMockSkillSummary("id1", PublishStatus.Draft) + ] + expect(component["addToWorkspaceVisible"]()).toBeTrue() + }) }) From ebd25cbaa923f2b350f1da0adb473b9a12842953 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 10 Feb 2023 14:37:40 -0600 Subject: [PATCH 057/150] Remove undesired changes --- ui/src/app/auth/auth-service.ts | 6 ---- .../collection-skill-search.component.ts | 32 +++++++++---------- .../list/skills-list.component.spec.ts | 24 +++++++------- .../richskill/list/skills-list.component.ts | 30 ++++++++--------- 4 files changed, 43 insertions(+), 49 deletions(-) diff --git a/ui/src/app/auth/auth-service.ts b/ui/src/app/auth/auth-service.ts index 7d18d2075..f850a570d 100644 --- a/ui/src/app/auth/auth-service.ts +++ b/ui/src/app/auth/auth-service.ts @@ -9,7 +9,6 @@ import { IAuthService } from "./iauth-service" export const STORAGE_KEY_TOKEN = "OSMT.AuthService.accessToken" export const STORAGE_KEY_RETURN = "OSMT.AuthService.return" export const STORAGE_KEY_ROLE = "OSMT.AuthService.role" -export const STORAGE_KEY_EMAIL = "OSMT.AuthService.email" @Injectable() export class AuthService extends Whitelabelled implements IAuthService { @@ -37,7 +36,6 @@ export class AuthService extends Whitelabelled implements IAuthService { storeToken(accessToken: string): void { localStorage.setItem(STORAGE_KEY_TOKEN, accessToken) - localStorage.setItem(STORAGE_KEY_EMAIL, JSON.parse(atob(accessToken.split(".")[1]))?.email) localStorage.setItem(STORAGE_KEY_ROLE, JSON.parse(atob(accessToken.split(".")[1]))?.roles) } @@ -54,10 +52,6 @@ export class AuthService extends Whitelabelled implements IAuthService { return ret } - getEmail(): string | null { - return localStorage.getItem(STORAGE_KEY_EMAIL) - } - logout(): void { localStorage.removeItem(STORAGE_KEY_TOKEN) } diff --git a/ui/src/app/collection/collection-skill-search.component.ts b/ui/src/app/collection/collection-skill-search.component.ts index f41b69afd..d35605da3 100644 --- a/ui/src/app/collection/collection-skill-search.component.ts +++ b/ui/src/app/collection/collection-skill-search.component.ts @@ -1,19 +1,19 @@ -import {Component, OnInit} from "@angular/core" -import {Observable} from "rxjs" -import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../richskill/service/rich-skill-search.service" -import {FormControl, FormGroup} from "@angular/forms" -import {ActivatedRoute, Router} from "@angular/router" -import {Title} from "@angular/platform-browser" -import {Location} from "@angular/common" -import {CollectionService} from "./service/collection.service" -import {ToastService} from "../toast/toast.service" -import {ApiCollection} from "./ApiCollection" -import {RichSkillService} from "../richskill/service/rich-skill.service" -import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions" -import {ApiSkillSummary} from "../richskill/ApiSkillSummary" -import {SkillsListComponent} from "../richskill/list/skills-list.component" -import {ApiTaskResult} from "../task/ApiTaskResult" -import {AuthService} from "../auth/auth-service" +import {Component, OnInit} from "@angular/core"; +import {Observable} from "rxjs"; +import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../richskill/service/rich-skill-search.service"; +import {FormControl, FormGroup} from "@angular/forms"; +import {ActivatedRoute, Router} from "@angular/router"; +import {Title} from "@angular/platform-browser"; +import {Location} from "@angular/common"; +import {CollectionService} from "./service/collection.service"; +import {ToastService} from "../toast/toast.service"; +import {ApiCollection} from "./ApiCollection"; +import {RichSkillService} from "../richskill/service/rich-skill.service"; +import {TableActionDefinition} from "../table/skills-library-table/has-action-definitions"; +import {ApiSkillSummary} from "../richskill/ApiSkillSummary"; +import {SkillsListComponent} from "../richskill/list/skills-list.component"; +import {ApiTaskResult} from "../task/ApiTaskResult"; +import {AuthService} from "../auth/auth-service"; import {PublishStatus} from "../PublishStatus" @Component({ diff --git a/ui/src/app/richskill/list/skills-list.component.spec.ts b/ui/src/app/richskill/list/skills-list.component.spec.ts index ee361546f..622e33eea 100644 --- a/ui/src/app/richskill/list/skills-list.component.spec.ts +++ b/ui/src/app/richskill/list/skills-list.component.spec.ts @@ -1,19 +1,19 @@ // noinspection MagicNumberJS,LocalVariableNamingConventionJS -import {Component, ElementRef, Type} from "@angular/core" -import {async, ComponentFixture, TestBed} from "@angular/core/testing" -import {RouterTestingModule} from "@angular/router/testing" -import {createMockCollection, createMockPaginatedSkills, createMockSkillSummary} from "../../../../test/resource/mock-data" +import { Component, ElementRef, Type } from "@angular/core" +import { async, ComponentFixture, TestBed } from "@angular/core/testing" +import { RouterTestingModule } from "@angular/router/testing" +import { createMockPaginatedSkills, createMockSkillSummary } from "../../../../test/resource/mock-data" import {AuthServiceStub, CollectionServiceStub, RichSkillServiceStub} from "../../../../test/resource/mock-stubs" -import {PublishStatus} from "../../PublishStatus" -import {ToastService} from "../../toast/toast.service" -import {ApiSortOrder} from "../ApiSkill" -import {ApiSearch, PaginatedSkills} from "../service/rich-skill-search.service" -import {RichSkillService} from "../service/rich-skill.service" -import {SkillsListComponent} from "./skills-list.component" -import {AuthService} from "../../auth/auth-service" -import {CollectionService} from "../../collection/service/collection.service" +import { PublishStatus } from "../../PublishStatus" +import { ToastService } from "../../toast/toast.service" +import { ApiSortOrder } from "../ApiSkill" +import { ApiSearch, PaginatedSkills } from "../service/rich-skill-search.service" +import { RichSkillService } from "../service/rich-skill.service" +import { SkillsListComponent } from "./skills-list.component" +import {AuthService} from "../../auth/auth-service"; import {HttpClientModule} from "@angular/common/http" +import {CollectionService} from "../../collection/service/collection.service" @Component({ diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index a25d37272..f14ab1480 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -1,19 +1,19 @@ import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../service/rich-skill-search.service" -import {ApiSkillSummary} from "../ApiSkillSummary" -import {checkArchived, determineFilters, PublishStatus} from "../../PublishStatus" -import {TableActionDefinition} from "../../table/skills-library-table/has-action-definitions" -import {Component, ElementRef, ViewChild} from "@angular/core" -import {Observable} from "rxjs" -import {ApiBatchResult} from "../ApiBatchResult" -import {RichSkillService} from "../service/rich-skill.service" -import {ToastService} from "../../toast/toast.service" -import {ApiSortOrder} from "../ApiSkill" -import {Router} from "@angular/router" -import {QuickLinksHelper} from "../../core/quick-links-helper" -import {ExtrasSelectedSkillsState} from "../../collection/add-skills-collection.component" -import {TableActionBarComponent} from "../../table/skills-library-table/table-action-bar.component" -import {AuthService} from "../../auth/auth-service" -import {ButtonAction} from "../../auth/auth-roles" +import {ApiSkillSummary} from "../ApiSkillSummary"; +import {checkArchived, determineFilters, PublishStatus} from "../../PublishStatus"; +import {TableActionDefinition} from "../../table/skills-library-table/has-action-definitions"; +import {Component, ElementRef, ViewChild} from "@angular/core"; +import {Observable} from "rxjs"; +import {ApiBatchResult} from "../ApiBatchResult"; +import {RichSkillService} from "../service/rich-skill.service"; +import {ToastService} from "../../toast/toast.service"; +import {ApiSortOrder} from "../ApiSkill"; +import {Router} from "@angular/router"; +import {QuickLinksHelper} from "../../core/quick-links-helper"; +import {ExtrasSelectedSkillsState} from "../../collection/add-skills-collection.component"; +import {TableActionBarComponent} from "../../table/skills-library-table/table-action-bar.component"; +import {AuthService} from "../../auth/auth-service"; +import {ButtonAction} from "../../auth/auth-roles"; import {CollectionService} from "../../collection/service/collection.service" import {ApiCollection} from "../../collection/ApiCollection" import {CollectionPipe} from "../../pipes" From 63c95898370bf8757ed95b93bba0d6fb71dd281d Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:04:09 -0600 Subject: [PATCH 058/150] Curator fix - Fix notifications, buttons. --- ui/src/app/collection/detail/manage-collection.component.ts | 2 +- ui/src/app/my-workspace/my-workspace.component.ts | 5 ----- ui/src/app/richskill/list/skills-list.component.ts | 3 +++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ui/src/app/collection/detail/manage-collection.component.ts b/ui/src/app/collection/detail/manage-collection.component.ts index ac025f72c..61e77518e 100644 --- a/ui/src/app/collection/detail/manage-collection.component.ts +++ b/ui/src/app/collection/detail/manage-collection.component.ts @@ -356,7 +356,7 @@ export class ManageCollectionComponent extends SkillsListComponent implements On this.skillsSaved = this.collectionService.updateSkillsWithResult(this.uuidParam ?? "", update) this.skillsSaved.subscribe(result => { if (result) { - this.toastService.showToast("Success!", `You removed ${result.modifiedCount} RSD${(result.modifiedCount ?? 0) > 1 ? "s" : ""} from this collection.`) + this.toastService.showToast("Success!", `You removed ${result.modifiedCount} RSD${(result.modifiedCount ?? 0) > 1 ? "s" : ""} from this ${this.collectionOrWorkspace(false).toLowerCase()}`) this.toastService.hideBlockingLoader() this.reloadCollection() this.loadNextPage() diff --git a/ui/src/app/my-workspace/my-workspace.component.ts b/ui/src/app/my-workspace/my-workspace.component.ts index 59428e03b..4d58008d3 100644 --- a/ui/src/app/my-workspace/my-workspace.component.ts +++ b/ui/src/app/my-workspace/my-workspace.component.ts @@ -102,9 +102,4 @@ export class MyWorkspaceComponent extends ManageCollectionComponent implements O this.router.navigate([`/my-workspace/${this.collection?.uuid}/add-skills`]) } - addToCollectionVisible(): boolean { - return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.MyWorkspace) - } - - } diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index f14ab1480..da5d3657b 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -155,6 +155,9 @@ export class SkillsListComponent extends QuickLinksHelper { } addToCollectionVisible(skill?: ApiSkillSummary): boolean { + if (this.collection?.status === PublishStatus.Workspace) { + return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.MyWorkspace) + } return this.addToVisible() && this.authService.isEnabledByRoles(ButtonAction.CollectionSkillsUpdate) } From 8b5e474a3d1c47a1f34319687baed48adc3dd964 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Mon, 13 Feb 2023 10:11:58 -0600 Subject: [PATCH 059/150] Correcting status check for Collection in CSV donwload endpoint --- .../main/kotlin/edu/wgu/osmt/collection/CollectionController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt index deac351bc..0c4219b9d 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/CollectionController.kt @@ -177,7 +177,7 @@ class CollectionController @Autowired constructor( fun getSkillsForCollectionCsv( @PathVariable uuid: String ): HttpEntity { - if (collectionRepository.findByUUID(uuid)!!.publishStatus() == PublishStatus.Draft && !oAuthHelper.hasRole(appConfig.roleAdmin)) { + if (collectionRepository.findByUUID(uuid)!!.status == PublishStatus.Draft && !oAuthHelper.hasRole(appConfig.roleAdmin)) { throw ResponseStatusException(HttpStatus.UNAUTHORIZED) } val task = CsvTask(collectionUuid = uuid) From 18b9a96022e69bd7416a1304fd3c70b1b57c3574 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 13 Feb 2023 12:29:30 -0600 Subject: [PATCH 060/150] Add new components --- ui/src/app/app-routing.module.ts | 5 + ui/src/app/app.module.ts | 19 ++-- ui/src/app/form/form.module.ts | 35 ++++++ .../search-multi-select.component.html | 103 ++++++++++++++++++ .../search-multi-select.component.scss | 0 .../search-multi-select.component.spec.ts | 25 +++++ .../search-multi-select.component.ts | 23 ++++ .../app/shared/filter/filter.component.html | 2 + .../app/shared/filter/filter.component.scss | 0 .../shared/filter/filter.component.spec.ts | 25 +++++ ui/src/app/shared/filter/filter.component.ts | 19 ++++ ui/src/app/shared/shared.module.ts | 20 ++++ 12 files changed, 264 insertions(+), 12 deletions(-) create mode 100644 ui/src/app/form/form.module.ts create mode 100644 ui/src/app/form/search-multi-select/search-multi-select.component.html create mode 100644 ui/src/app/form/search-multi-select/search-multi-select.component.scss create mode 100644 ui/src/app/form/search-multi-select/search-multi-select.component.spec.ts create mode 100644 ui/src/app/form/search-multi-select/search-multi-select.component.ts create mode 100644 ui/src/app/shared/filter/filter.component.html create mode 100644 ui/src/app/shared/filter/filter.component.scss create mode 100644 ui/src/app/shared/filter/filter.component.spec.ts create mode 100644 ui/src/app/shared/filter/filter.component.ts create mode 100644 ui/src/app/shared/shared.module.ts diff --git a/ui/src/app/app-routing.module.ts b/ui/src/app/app-routing.module.ts index ca963e124..ee7f14dde 100644 --- a/ui/src/app/app-routing.module.ts +++ b/ui/src/app/app-routing.module.ts @@ -23,6 +23,7 @@ import {BatchImportComponent} from "./richskill/import/batch-import.component" import { ActionByRoles, ButtonAction } from "./auth/auth-roles" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" import {ConvertToCollectionComponent} from "./my-workspace/convert-to-collection/convert-to-collection.component" +import {FilterComponent} from "./shared/filter/filter.component" const routes: Routes = [ @@ -167,6 +168,10 @@ const routes: Routes = [ roles: ActionByRoles.get(ButtonAction.MyWorkspace) } }, + { + path: "test", + component: FilterComponent + }, /* PUBLIC VIEWS */ {path: "skills/:uuid", component: RichSkillPublicComponent}, {path: "collections/:uuid", component: CollectionPublicComponent}, diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index d02fc5c15..05f1fbdd2 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -9,13 +9,9 @@ import {RichSkillsLibraryComponent} from "./richskill/library/rich-skills-librar import {RichSkillPublicComponent} from "./richskill/detail/rich-skill-public/rich-skill-public.component" import {AppConfig} from "./app.config" import {RichSkillFormComponent} from "./richskill/form/rich-skill-form.component" -import {ReactiveFormsModule} from "@angular/forms" -import {FormField} from "./form/form-field.component" -import {FormFieldText} from "./form/form-field-text.component" -import {FormFieldTextArea} from "./form/form-field-textarea.component" +import {FormsModule, ReactiveFormsModule} from "@angular/forms" import {LoadingObservablesDirective} from "./loading/loading-observables.directive" import {LoadingComponent} from "./loading/loading.component" -import {FormFieldSubmit} from "./form/form-field-submit.component" import {HeaderComponent} from "./navigation/header.component" import {FooterComponent} from "./navigation/footer.component" import {SkillCollectionsDisplayComponent} from "./richskill/form/skill-collections-display.component" @@ -86,7 +82,6 @@ import { NamedReferenceComponent } from "./richskill/import/import-preview-table.component" import {FormFieldSearchSelectComponent} from "./form/form-field-search-select/single-select/form-field-search-select.component" -import {FormFieldSearchMultiSelectComponent} from "./form/form-field-search-select/mulit-select/form-field-search-multi-select.component" import {FormFieldSearchSelectJobcodeComponent} from "./form/form-field-search-select/jobcode-select/form-field-search-select-jobcode.component" import {AuditLogComponent} from "./richskill/detail/audit-log.component" import {OccupationsCardSectionComponent} from "./richskill/detail/occupations-card-section/occupations-card-section.component" @@ -100,6 +95,8 @@ import {LibraryExportComponent} from "./navigation/libraryexport.component" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" import {CollectionPipe} from "./pipes" import { ConvertToCollectionComponent } from "./my-workspace/convert-to-collection/convert-to-collection.component" +import {SharedModule} from "./shared/shared.module" +import {FormModule} from "./form/form.module" export function initializeApp( appConfig: AppConfig, @@ -129,10 +126,6 @@ export function initializeApp( // Rich skill form RichSkillFormComponent, - FormField, - FormFieldSubmit, - FormFieldText, - FormFieldTextArea, // Rich skills RichSkillsLibraryComponent, @@ -204,7 +197,6 @@ export function initializeApp( NamedReferenceComponent, InlineErrorComponent, FormFieldSearchSelectComponent, - FormFieldSearchMultiSelectComponent, FormFieldSearchSelectJobcodeComponent, AuditLogComponent, OccupationsCardSectionComponent, @@ -220,7 +212,10 @@ export function initializeApp( AppRoutingModule, HttpClientModule, ReactiveFormsModule, - CommonModule + FormsModule, + CommonModule, + SharedModule, + FormModule ], providers: [ EnvironmentService, diff --git a/ui/src/app/form/form.module.ts b/ui/src/app/form/form.module.ts new file mode 100644 index 000000000..792787115 --- /dev/null +++ b/ui/src/app/form/form.module.ts @@ -0,0 +1,35 @@ +import { NgModule } from "@angular/core" +import { CommonModule } from "@angular/common" +import { FormFieldSearchMultiSelectComponent } from "./form-field-search-select/mulit-select/form-field-search-multi-select.component" +import { SearchMultiSelectComponent } from "./search-multi-select/search-multi-select.component" +import { FormField } from "./form-field.component" +import { FormFieldSubmit } from "./form-field-submit.component" +import { FormFieldText } from "./form-field-text.component" +import { FormFieldTextArea } from "./form-field-textarea.component" +import { FormsModule, ReactiveFormsModule } from "@angular/forms" + +@NgModule({ + declarations: [ + FormFieldSearchMultiSelectComponent, + SearchMultiSelectComponent, + FormField, + FormFieldSubmit, + FormFieldText, + FormFieldTextArea + ], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule + ], + exports: [ + FormFieldSearchMultiSelectComponent, + SearchMultiSelectComponent, + FormField, + FormFieldSubmit, + FormFieldText, + FormFieldTextArea + ] +}) +export class FormModule { +} diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.html b/ui/src/app/form/search-multi-select/search-multi-select.component.html new file mode 100644 index 000000000..9b71422ae --- /dev/null +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.html @@ -0,0 +1,103 @@ + +
    + + +
    +
    +
    +

    + Loading… + +

    +
    +
    +
    + + + +
    +
    + + +
    +
    Showing search results:
    + +
    + + + +
    +

    + No Results +

    +
    +
    +
    +
    +
    + + +
    + + {{r}} + +
    + +
    +
    +
    +
    diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.scss b/ui/src/app/form/search-multi-select/search-multi-select.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.spec.ts b/ui/src/app/form/search-multi-select/search-multi-select.component.spec.ts new file mode 100644 index 000000000..5ab61ac1b --- /dev/null +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing" + +import { SearchMultiSelectComponent } from "./search-multi-select.component" + +describe("SearchMultiSelectComponent", () => { + let component: SearchMultiSelectComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SearchMultiSelectComponent ] + }) + .compileComponents() + }) + + beforeEach(() => { + fixture = TestBed.createComponent(SearchMultiSelectComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it("should create", () => { + expect(component).toBeTruthy() + }) +}) diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.ts b/ui/src/app/form/search-multi-select/search-multi-select.component.ts new file mode 100644 index 000000000..955f48ca1 --- /dev/null +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.ts @@ -0,0 +1,23 @@ +import {Component, OnInit} from "@angular/core" +import {KeywordSearchService} from "../../richskill/service/keyword-search.service" +import { + FormFieldSearchMultiSelectComponent +} from "../form-field-search-select/mulit-select/form-field-search-multi-select.component" + +@Component({ + selector: "app-search-multi-select", + templateUrl: "./search-multi-select.component.html", + styleUrls: ["./search-multi-select.component.scss"] +}) +export class SearchMultiSelectComponent extends FormFieldSearchMultiSelectComponent implements OnInit { + + constructor(protected searchService: KeywordSearchService) { + super(searchService) + } + + ngOnInit(): void { + super.ngOnInit() + this.performInitialSearchAndPopulation() + } + +} diff --git a/ui/src/app/shared/filter/filter.component.html b/ui/src/app/shared/filter/filter.component.html new file mode 100644 index 000000000..bf07d867a --- /dev/null +++ b/ui/src/app/shared/filter/filter.component.html @@ -0,0 +1,2 @@ + + diff --git a/ui/src/app/shared/filter/filter.component.scss b/ui/src/app/shared/filter/filter.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/ui/src/app/shared/filter/filter.component.spec.ts b/ui/src/app/shared/filter/filter.component.spec.ts new file mode 100644 index 000000000..d2f254c3e --- /dev/null +++ b/ui/src/app/shared/filter/filter.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing" + +import { FilterComponent } from "./filter.component" + +describe("FilterComponent", () => { + let component: FilterComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FilterComponent ] + }) + .compileComponents() + }) + + beforeEach(() => { + fixture = TestBed.createComponent(FilterComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it("should create", () => { + expect(component).toBeTruthy() + }) +}) diff --git a/ui/src/app/shared/filter/filter.component.ts b/ui/src/app/shared/filter/filter.component.ts new file mode 100644 index 000000000..c937cd1d2 --- /dev/null +++ b/ui/src/app/shared/filter/filter.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit } from "@angular/core" +import { KeywordType } from "../../richskill/ApiSkill" + +@Component({ + selector: "app-filter", + templateUrl: "./filter.component.html", + styleUrls: ["./filter.component.scss"] +}) +export class FilterComponent implements OnInit { + + keywordType = KeywordType + + constructor() { + } + + ngOnInit(): void { + } + +} diff --git a/ui/src/app/shared/shared.module.ts b/ui/src/app/shared/shared.module.ts new file mode 100644 index 000000000..0a47f3468 --- /dev/null +++ b/ui/src/app/shared/shared.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from "@angular/core" +import { CommonModule } from "@angular/common" +import { FilterComponent } from "./filter/filter.component" +import { FormsModule, ReactiveFormsModule } from "@angular/forms" +import {FormModule} from "../form/form.module" + + + +@NgModule({ + declarations: [ + FilterComponent + ], + imports: [ + CommonModule, + ReactiveFormsModule, + FormsModule, + FormModule + ] +}) +export class SharedModule { } From d70b8de08fde2961f6d9c95fed7c8684bba2c143 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Mon, 13 Feb 2023 13:07:04 -0600 Subject: [PATCH 061/150] Correcting workspace type check for Collections --- api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt index 6bfa87935..e166bae34 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/collection/Collection.kt @@ -30,7 +30,7 @@ data class Collection( fun canonicalUrl(baseUrl: String): String = "$baseUrl/api/collections/${uuid}" fun isWorkspace() : Boolean { - return (this.status == PublishStatus.Workspace && StringUtils.isNoneEmpty(this.workspaceOwner)) + return (this.status == PublishStatus.Workspace && StringUtils.isNotEmpty(this.workspaceOwner)) } } From 5244dc5ad44ea4683c0eebb39c41e404b28a6b4a Mon Sep 17 00:00:00 2001 From: John Kallies <3021949+JohnKallies@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:06:43 -0500 Subject: [PATCH 062/150] Update rqueue-spring-boot-starter to 2.13.0-RELEASE (#305) Patching for CVE: CVE-2022-37767 - Library: pebble-3.1.5.jar - Vulnerable version: 3.1.5 - Patched Version: 3.1.6 or 3.2.0 edu.wgu.osmt:osmt-api:jar:2.5.0-SNAPSHOT \- com.github.sonus21:rqueue-spring-boot-starter:jar:2.13.0-RELEASE:compile \- com.github.sonus21:rqueue-core:jar:2.13.0-RELEASE:compile \- io.pebbletemplates:pebble-spring5:jar:3.1.6:compile \- io.pebbletemplates:pebble:jar:3.1.6:compile --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 73f4ac019..7e94ee262 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -76,7 +76,7 @@ com.github.sonus21 rqueue-spring-boot-starter - 2.10.1-RELEASE + 2.13.0-RELEASE com.fasterxml.jackson.core From 87036096c13293fd604f8f4dee1fec6b0860fb30 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 13 Feb 2023 17:17:32 -0600 Subject: [PATCH 063/150] Add drop down --- ...orm-field-search-multi-select.component.ts | 2 +- .../search-multi-select.component.html | 26 +++------- .../search-multi-select.component.scss | 50 ++++++++++++++++++ .../search-multi-select.component.ts | 31 +++++++++++ .../app/shared/filter/filter.component.html | 47 ++++++++++++++++- .../app/shared/filter/filter.component.scss | 52 +++++++++++++++++++ ui/src/app/shared/filter/filter.component.ts | 22 +++++++- 7 files changed, 206 insertions(+), 24 deletions(-) diff --git a/ui/src/app/form/form-field-search-select/mulit-select/form-field-search-multi-select.component.ts b/ui/src/app/form/form-field-search-select/mulit-select/form-field-search-multi-select.component.ts index 06d5af037..8b5868b3e 100644 --- a/ui/src/app/form/form-field-search-select/mulit-select/form-field-search-multi-select.component.ts +++ b/ui/src/app/form/form-field-search-select/mulit-select/form-field-search-multi-select.component.ts @@ -52,7 +52,7 @@ export class FormFieldSearchMultiSelectComponent extends AbstractFormFieldSearch this.emitCurrentSelection() } - private emitCurrentSelection(): void { + protected emitCurrentSelection(): void { this.currentSelection.emit(this.internalSelectedResults) } diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.html b/ui/src/app/form/search-multi-select/search-multi-select.component.html index 9b71422ae..0e707604d 100644 --- a/ui/src/app/form/search-multi-select/search-multi-select.component.html +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.html @@ -22,7 +22,7 @@ [required]="required" class="m-search-x-input" type="text" - placeholder="Search" + placeholder="Type {{name}} to filter" [attr.aria-label]="name" role="search" [attr.aria-describedby]="name + '-results'" @@ -66,11 +66,12 @@
    Showing search results:
    - + +
    @@ -83,21 +84,6 @@
    -
    - - -
    - - {{r}} - -
    - -
    diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.scss b/ui/src/app/form/search-multi-select/search-multi-select.component.scss index e69de29bb..c53ebec0f 100644 --- a/ui/src/app/form/search-multi-select/search-multi-select.component.scss +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.scss @@ -0,0 +1,50 @@ +input[type=checkbox] { + position: relative; + cursor: pointer; +} + +input[type=checkbox]:before { + content: ""; + display: block; + position: absolute; + width: 15px; + height: 15px; + top: 0; + left: 0; + background-color:#e9e9e9; +} + +input[type=checkbox]:checked:before { + content: ""; + display: block; + position: absolute; + width: 20px; + height: 20px; + top: 0; + left: 0; + background-color:#1E80EF; +} + +input[type=checkbox]:checked:after { + content: ""; + display: block; + width: 5px; + height: 10px; + border: solid white; + border-width: 0 2px 2px 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + top: 2px; + left: 6px; +} + +.result-container { + display: flex; + justify-content: space-between; +} + +.result-container:nth-child(odd) { + background: #434647; +} diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.ts b/ui/src/app/form/search-multi-select/search-multi-select.component.ts index 955f48ca1..e543f85c5 100644 --- a/ui/src/app/form/search-multi-select/search-multi-select.component.ts +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.ts @@ -20,4 +20,35 @@ export class SearchMultiSelectComponent extends FormFieldSearchMultiSelectCompon this.performInitialSearchAndPopulation() } + selectResult(result: string): void { + const isResultSelected = this.isResultSelected(result) + if (!isResultSelected) { + this.internalSelectedResults.push(result) + } else { + this.internalSelectedResults = this.internalSelectedResults.filter(r => r !== result) + } + super.emitCurrentSelection() + } + + performSearch(text: string): void { + if (!text) { + return // no search to perform + } + this.currentlyLoading = true + + if (this.queryInProgress) { + this.queryInProgress.unsubscribe() // unsub to existing query first + } + + this.queryInProgress = this.keywordType ? this.searchService.searchKeywords(this.keywordType, text) + .subscribe(searchResults => { + this.results = searchResults.filter(r => !!r && !!r.name).map(r => r.name as string) + this.currentlyLoading = false + }) : this.searchService.searchJobcodes(text) + .subscribe(searchResults => { + this.results = searchResults.filter(r => !!r && !!r.code && !!r.targetNodeName).map(i => i.targetNodeName ?? "") + this.currentlyLoading = false + }) + } + } diff --git a/ui/src/app/shared/filter/filter.component.html b/ui/src/app/shared/filter/filter.component.html index bf07d867a..d99558978 100644 --- a/ui/src/app/shared/filter/filter.component.html +++ b/ui/src/app/shared/filter/filter.component.html @@ -1,2 +1,45 @@ - - + diff --git a/ui/src/app/shared/filter/filter.component.scss b/ui/src/app/shared/filter/filter.component.scss index e69de29bb..076ca607b 100644 --- a/ui/src/app/shared/filter/filter.component.scss +++ b/ui/src/app/shared/filter/filter.component.scss @@ -0,0 +1,52 @@ +.apply-filter-button { + background: white; + color: #002F50; +} + +.apply-filter-button:hover { + color: white; + background: #002F50; +} + +.apply-filter-button:focus { + color: white; + background: #002F50; +} + +/**drop down**/ +.drop-button { + color: white; + padding: 16px; + font-size: 16px; + border: none; +} + +.dropdown { + position: relative; + display: inline-block; +} + +.dropdown-content { + display: none; + position: absolute; + // background-color: #f1f1f1; + min-width: 160px; + z-index: 1; +} + +.dropdown-content a { + color: black; + padding: 12px 16px; + text-decoration: none; + display: block; +} + +.dropdown-content a:hover { + // background-color: #ccc; + margin-bottom: 20px; +} + +.dropdown:hover .dropdown-content.dropdown-content-visible { + display: block; + margin-bottom: 30px; +} diff --git a/ui/src/app/shared/filter/filter.component.ts b/ui/src/app/shared/filter/filter.component.ts index c937cd1d2..90dd54042 100644 --- a/ui/src/app/shared/filter/filter.component.ts +++ b/ui/src/app/shared/filter/filter.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from "@angular/core" import { KeywordType } from "../../richskill/ApiSkill" +import { FormBuilder, FormGroup } from "@angular/forms" @Component({ selector: "app-filter", @@ -8,12 +9,31 @@ import { KeywordType } from "../../richskill/ApiSkill" }) export class FilterComponent implements OnInit { + showInputs = false + filterFg: FormGroup + keywordType = KeywordType - constructor() { + constructor(private formBuilder: FormBuilder) { + this.filterFg = this.configureFilterFg() } ngOnInit(): void { } + private configureFilterFg(): FormGroup { + return this.formBuilder.group({ + categories: "", + keywords: "", + standards: "", + certifications: "", + occupations: "", + employers: "" + }) + } + + onApplyFilter(): void { + this.showInputs = !this.showInputs + } + } From ea1e0616ec5285dbe5b9e3271f88303a99ba989b Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 13 Feb 2023 18:21:17 -0600 Subject: [PATCH 064/150] Add filter menu --- ui/src/app/app-routing.module.ts | 5 --- .../search-multi-select.component.scss | 1 + .../app/shared/filter/filter.component.html | 1 + .../app/shared/filter/filter.component.scss | 8 +++- ui/src/app/shared/shared.module.ts | 3 ++ .../filter-controls.component.html | 39 +++++++++++-------- .../filter-controls.component.scss | 4 ++ .../filter-controls.component.ts | 3 +- 8 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 ui/src/app/table/filter-controls/filter-controls.component.scss diff --git a/ui/src/app/app-routing.module.ts b/ui/src/app/app-routing.module.ts index ee7f14dde..ca963e124 100644 --- a/ui/src/app/app-routing.module.ts +++ b/ui/src/app/app-routing.module.ts @@ -23,7 +23,6 @@ import {BatchImportComponent} from "./richskill/import/batch-import.component" import { ActionByRoles, ButtonAction } from "./auth/auth-roles" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" import {ConvertToCollectionComponent} from "./my-workspace/convert-to-collection/convert-to-collection.component" -import {FilterComponent} from "./shared/filter/filter.component" const routes: Routes = [ @@ -168,10 +167,6 @@ const routes: Routes = [ roles: ActionByRoles.get(ButtonAction.MyWorkspace) } }, - { - path: "test", - component: FilterComponent - }, /* PUBLIC VIEWS */ {path: "skills/:uuid", component: RichSkillPublicComponent}, {path: "collections/:uuid", component: CollectionPublicComponent}, diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.scss b/ui/src/app/form/search-multi-select/search-multi-select.component.scss index c53ebec0f..b7cc03dbd 100644 --- a/ui/src/app/form/search-multi-select/search-multi-select.component.scss +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.scss @@ -1,4 +1,5 @@ input[type=checkbox] { + margin-right: 20px; position: relative; cursor: pointer; } diff --git a/ui/src/app/shared/filter/filter.component.html b/ui/src/app/shared/filter/filter.component.html index d99558978..d0bb64d8e 100644 --- a/ui/src/app/shared/filter/filter.component.html +++ b/ui/src/app/shared/filter/filter.component.html @@ -3,6 +3,7 @@ + Filter +
    + + +
    From 661e2981271e9ee691b3f7b5e3d511e26daac4f8 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 14 Feb 2023 18:03:34 -0600 Subject: [PATCH 073/150] Remove extends --- .../search-multi-select.component.html | 133 ++++++++---------- .../search-multi-select.component.scss | 2 +- .../search-multi-select.component.ts | 56 +++++--- .../filter-dropdown.component.html | 1 + .../filter-dropdown.component.ts | 18 ++- .../filter-controls.component.html | 4 +- .../filter-controls.component.ts | 3 + 7 files changed, 122 insertions(+), 95 deletions(-) diff --git a/ui/src/app/form/search-multi-select/search-multi-select.component.html b/ui/src/app/form/search-multi-select/search-multi-select.component.html index 41bb03c21..17c206c69 100644 --- a/ui/src/app/form/search-multi-select/search-multi-select.component.html +++ b/ui/src/app/form/search-multi-select/search-multi-select.component.html @@ -2,93 +2,84 @@ {{name | titlecase}} - -
    - @@ -29,32 +29,32 @@

    Filters

    + *ngIf="chipsValues.categories?.length > 0"> + *ngIf="chipsValues.keywords?.length > 0"> + *ngIf="chipsValues.standards?.length > 0"> + *ngIf="chipsValues.certifications?.length > 0"> + *ngIf="chipsValues.occupations?.length > 0"> + *ngIf="chipsValues.employers?.length > 0">
    diff --git a/ui/src/app/table/filter-controls/filter-controls.component.ts b/ui/src/app/table/filter-controls/filter-controls.component.ts index 35b5e60f2..60f8d55be 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.ts +++ b/ui/src/app/table/filter-controls/filter-controls.component.ts @@ -9,7 +9,9 @@ import {FilterDropdown} from "../../models/filter-dropdown.model" }) export class FilterControlsComponent implements OnInit { @Input() selectedFilters: Set = new Set() + @Output() keywordsChanged: EventEmitter = new EventEmitter() @Output() filtersChanged: EventEmitter> = new EventEmitter>() + @Input() chipsValues: FilterDropdown = { categories: [], certifications: [], @@ -50,4 +52,9 @@ export class FilterControlsComponent implements OnInit { isStatusChecked(status: PublishStatus): boolean | undefined { return this.selectedFilters.has(status) ? true : undefined } + + applyFilter(event: FilterDropdown): void { + this.chipsValues = event + this.keywordsChanged.emit(this.chipsValues) + } } From 63cd7ccc94eabdc6145e6e29fc53cb0a62e0e2fb Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:15:29 -0600 Subject: [PATCH 089/150] Refactor variable name --- .../richskill/list/skills-list.component.html | 2 +- .../filter-chips/filter-chips.component.html | 4 +-- .../filter-chips.component.spec.ts | 4 +-- .../filter-chips/filter-chips.component.ts | 6 ++--- .../filter-dropdown.component.html | 2 +- .../filter-dropdown.component.ts | 4 +-- .../filter-controls.component.html | 26 +++++++++---------- .../filter-controls.component.ts | 6 ++--- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/ui/src/app/richskill/list/skills-list.component.html b/ui/src/app/richskill/list/skills-list.component.html index 9a59ce745..1c8254456 100644 --- a/ui/src/app/richskill/list/skills-list.component.html +++ b/ui/src/app/richskill/list/skills-list.component.html @@ -26,7 +26,7 @@

    diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.html b/ui/src/app/shared/filter-chips/filter-chips.component.html index eb7c80457..2be62b92b 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.html +++ b/ui/src/app/shared/filter-chips/filter-chips.component.html @@ -1,7 +1,7 @@
    {{name | titlecase}}
    -
    - {{chip}} +
    + {{keyword}} ×
    diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts b/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts index e4087f316..5b5bdf105 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts +++ b/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts @@ -24,8 +24,8 @@ describe("FilterChipsComponent", () => { }) it("remove chip should remove and element from chips", () => { - component.chips = ["chip1", "chip2"] + component.keywords = ["chip1", "chip2"] component.onRemoveChip("chip1") - expect(component.chips.length).toBe(1) + expect(component.keywords.length).toBe(1) }) }) diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.ts b/ui/src/app/shared/filter-chips/filter-chips.component.ts index 5bd200eae..b43a9f939 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.ts +++ b/ui/src/app/shared/filter-chips/filter-chips.component.ts @@ -10,7 +10,7 @@ export class FilterChipsComponent implements OnInit { @Input() name?: string @Input() - chips?: string[] + keywords?: string[] constructor() { } @@ -19,9 +19,9 @@ export class FilterChipsComponent implements OnInit { } onRemoveChip(chipText: string): void { - const index = this.chips?.findIndex(i => i === chipText) ?? 0 + const index = this.keywords?.findIndex(i => i === chipText) ?? 0 if (index >= 0) { - this.chips?.splice(index, 1) + this.keywords?.splice(index, 1) } } diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html index 63c821694..049275e40 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html @@ -17,7 +17,7 @@

    diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts index 468dd468c..ab2d0b7a1 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts @@ -17,14 +17,14 @@ export class FilterDropdownComponent implements OnInit { keywordType = KeywordType @Input() - chipsValues?: FilterDropdown + keywords?: FilterDropdown constructor(private formBuilder: FormBuilder) { this.filterFg = this.configureFilterFg() } ngOnInit(): void { - this.filterFg.patchValue(this.chipsValues ?? {}) + this.filterFg.patchValue(this.keywords ?? {}) } private configureFilterFg(): FormGroup { diff --git a/ui/src/app/table/filter-controls/filter-controls.component.html b/ui/src/app/table/filter-controls/filter-controls.component.html index f481ef3d2..2b4bdc555 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.html +++ b/ui/src/app/table/filter-controls/filter-controls.component.html @@ -20,7 +20,7 @@

    Filters

    >
    - +
    @@ -28,33 +28,33 @@

    Filters

    + [keywords]="keywords.categories" + *ngIf="keywords.categories?.length > 0"> + [keywords]="keywords.keywords" + *ngIf="keywords.keywords?.length > 0"> + [keywords]="keywords.standards" + *ngIf="keywords.standards?.length > 0"> + [keywords]="keywords.certifications" + *ngIf="keywords.certifications?.length > 0"> + [keywords]="keywords.occupations" + *ngIf="keywords.occupations?.length > 0"> + [keywords]="keywords.employers" + *ngIf="keywords.employers?.length > 0">
    diff --git a/ui/src/app/table/filter-controls/filter-controls.component.ts b/ui/src/app/table/filter-controls/filter-controls.component.ts index 60f8d55be..673f8b3a6 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.ts +++ b/ui/src/app/table/filter-controls/filter-controls.component.ts @@ -12,7 +12,7 @@ export class FilterControlsComponent implements OnInit { @Output() keywordsChanged: EventEmitter = new EventEmitter() @Output() filtersChanged: EventEmitter> = new EventEmitter>() @Input() - chipsValues: FilterDropdown = { + keywords: FilterDropdown = { categories: [], certifications: [], employers: [], @@ -54,7 +54,7 @@ export class FilterControlsComponent implements OnInit { } applyFilter(event: FilterDropdown): void { - this.chipsValues = event - this.keywordsChanged.emit(this.chipsValues) + this.keywords = event + this.keywordsChanged.emit(this.keywords) } } From c1a5c638e9912fbc6273758f45d981158a6fcea9 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:29:40 -0600 Subject: [PATCH 090/150] Reload on change drop down filter --- ui/src/app/richskill/list/skills-list.component.html | 4 ++-- ui/src/app/richskill/list/skills-list.component.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ui/src/app/richskill/list/skills-list.component.html b/ui/src/app/richskill/list/skills-list.component.html index 1c8254456..d0ed10abe 100644 --- a/ui/src/app/richskill/list/skills-list.component.html +++ b/ui/src/app/richskill/list/skills-list.component.html @@ -26,8 +26,8 @@

    diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index d4e07d231..51c00a168 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -18,6 +18,7 @@ import {CollectionService} from "../../collection/service/collection.service" import {ApiCollection} from "../../collection/ApiCollection" import {CollectionPipe} from "../../pipes" import {FilterDropdown} from "../../models/filter-dropdown.model" +import {FormBuilder, FormGroup} from "@angular/forms" @Component({ selector: "app-skills-list", @@ -37,7 +38,7 @@ export class SkillsListComponent extends QuickLinksHelper { results: PaginatedSkills | undefined selectedFilters: Set = new Set([PublishStatus.Draft, PublishStatus.Published]) - filterDropdown: FilterDropdown = { + keywords: FilterDropdown = { categories: [], certifications: [], employers: [], @@ -436,4 +437,10 @@ export class SkillsListComponent extends QuickLinksHelper { collectionOrWorkspace(includesMy: boolean): string { return new CollectionPipe().transform(this.collection?.status, includesMy) } + + keywordsChange(keywords: FilterDropdown): void { + this.keywords = keywords + this.loadNextPage() + } + } From 2c6ee1182aecead48b7dd5a19637348c3f7166aa Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 20 Feb 2023 15:34:39 -0600 Subject: [PATCH 091/150] Refactor form group - Change form group to filter controls. --- .../filter-chips/filter-chips.component.html | 2 +- .../filter-chips/filter-chips.component.ts | 19 +++++------- .../filter-dropdown.component.html | 14 ++++----- .../filter-dropdown.component.ts | 23 +++----------- .../filter-controls.component.html | 26 ++++++++-------- .../filter-controls.component.ts | 31 +++++++++++++------ 6 files changed, 54 insertions(+), 61 deletions(-) diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.html b/ui/src/app/shared/filter-chips/filter-chips.component.html index 2be62b92b..887f0e9af 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.html +++ b/ui/src/app/shared/filter-chips/filter-chips.component.html @@ -1,6 +1,6 @@
    {{name | titlecase}}
    -
    +
    {{keyword}} ×
    diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.ts b/ui/src/app/shared/filter-chips/filter-chips.component.ts index b43a9f939..5a5ea1577 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.ts +++ b/ui/src/app/shared/filter-chips/filter-chips.component.ts @@ -1,27 +1,24 @@ -import {Component, Input, OnInit, Output} from "@angular/core" +import {Component, Input} from "@angular/core" +import {FormControl} from "@angular/forms" @Component({ selector: "app-filter-chips", templateUrl: "./filter-chips.component.html", styleUrls: ["./filter-chips.component.scss"] }) -export class FilterChipsComponent implements OnInit { +export class FilterChipsComponent { @Input() name?: string @Input() - keywords?: string[] - - constructor() { - } - - ngOnInit(): void { - } + control?: FormControl onRemoveChip(chipText: string): void { - const index = this.keywords?.findIndex(i => i === chipText) ?? 0 + const values = this.control?.value + const index = this.control?.value?.findIndex((i: string) => i === chipText) ?? 0 if (index >= 0) { - this.keywords?.splice(index, 1) + values.splice(index, 1) + this.control?.patchValue(values) } } diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html index 049275e40..593dfddc1 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html @@ -18,36 +18,36 @@

    diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts index ab2d0b7a1..f435ad827 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts @@ -13,35 +13,20 @@ export class FilterDropdownComponent implements OnInit { @Output() applyFilter = new EventEmitter() showInputs = false - filterFg: FormGroup + @Input() + filterFg?: FormGroup keywordType = KeywordType @Input() keywords?: FilterDropdown - constructor(private formBuilder: FormBuilder) { - this.filterFg = this.configureFilterFg() - } - ngOnInit(): void { - this.filterFg.patchValue(this.keywords ?? {}) - } - - private configureFilterFg(): FormGroup { - return this.formBuilder.group({ - categories: [], - keywords: [], - standards: [], - alignment: [], - certifications: [], - occupations: [], - employers: [] - }) + this.filterFg?.patchValue(this.keywords ?? {}) } onApplyFilter(): void { this.showInputs = !this.showInputs - this.applyFilter.emit(this.filterFg.value) + this.applyFilter.emit(this.filterFg?.value) } } diff --git a/ui/src/app/table/filter-controls/filter-controls.component.html b/ui/src/app/table/filter-controls/filter-controls.component.html index 2b4bdc555..d75533edf 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.html +++ b/ui/src/app/table/filter-controls/filter-controls.component.html @@ -20,7 +20,7 @@

    Filters

    >
    - +
    @@ -28,33 +28,33 @@

    Filters

    + [control]="filterFg.get('categories')" + *ngIf="filterFg?.get('categories')?.value?.length > 0"> + [control]="filterFg.get('keywords')" + *ngIf="filterFg?.get('keywords')?.value?.length > 0"> + [control]="filterFg.get('standards')" + *ngIf="filterFg?.get('standards')?.value?.length > 0"> + [control]="filterFg.get('certifications')" + *ngIf="filterFg?.get('certifications')?.value?.length > 0"> + [control]="filterFg.get('occupations')" + *ngIf="filterFg?.get('occupations')?.value?.length > 0"> + [control]="filterFg.get('employers')" + *ngIf="filterFg?.get('employers')?.value?.length > 0">
    diff --git a/ui/src/app/table/filter-controls/filter-controls.component.ts b/ui/src/app/table/filter-controls/filter-controls.component.ts index 673f8b3a6..6601e8c6e 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.ts +++ b/ui/src/app/table/filter-controls/filter-controls.component.ts @@ -1,6 +1,7 @@ import {Component, EventEmitter, Input, OnInit, Output} from "@angular/core" import {PublishStatus} from "../../PublishStatus"; import {FilterDropdown} from "../../models/filter-dropdown.model" +import {FormBuilder, FormGroup} from "@angular/forms" @Component({ selector: "app-filter-controls", @@ -12,17 +13,14 @@ export class FilterControlsComponent implements OnInit { @Output() keywordsChanged: EventEmitter = new EventEmitter() @Output() filtersChanged: EventEmitter> = new EventEmitter>() @Input() - keywords: FilterDropdown = { - categories: [], - certifications: [], - employers: [], - alignments: [], - keywords: [], - occupations: [], - standards: [] - } + keywords?: FilterDropdown + filterFg: FormGroup - constructor() { + constructor( + protected formBuilder: FormBuilder + ) { + this.filterFg = this.configureFilterFg() + // this.keywords = this.filterFg.value } ngOnInit(): void { @@ -57,4 +55,17 @@ export class FilterControlsComponent implements OnInit { this.keywords = event this.keywordsChanged.emit(this.keywords) } + + private configureFilterFg(): FormGroup { + return this.formBuilder.group({ + categories: [], + keywords: [], + standards: [], + alignment: [], + certifications: [], + occupations: [], + employers: [] + }) + } + } From 5d89171fbfe3faaa4e3a6d768e12cb21bbd7505c Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 20 Feb 2023 15:42:31 -0600 Subject: [PATCH 092/150] Add alignment chips --- .../shared/filter-drop-down/filter-dropdown.component.html | 4 ++-- .../app/table/filter-controls/filter-controls.component.html | 5 +++++ .../app/table/filter-controls/filter-controls.component.scss | 2 +- .../app/table/filter-controls/filter-controls.component.ts | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html index 593dfddc1..8c8ace33f 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html @@ -32,8 +32,8 @@

    [keywordType]="keywordType.Standard"> Filters

    [control]="filterFg.get('standards')" *ngIf="filterFg?.get('standards')?.value?.length > 0"> + + Date: Mon, 20 Feb 2023 15:50:31 -0600 Subject: [PATCH 093/150] Remove unused code --- .../filter-drop-down/filter-dropdown.component.html | 1 - .../filter-drop-down/filter-dropdown.component.ts | 9 +-------- .../search-multi-select.component.html | 2 +- .../search-multi-select.component.ts | 10 +++------- .../filter-controls/filter-controls.component.html | 2 +- .../table/filter-controls/filter-controls.component.ts | 9 ++++++--- 6 files changed, 12 insertions(+), 21 deletions(-) diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html index 8c8ace33f..ffd6d60fe 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html @@ -17,7 +17,6 @@

    diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts index f435ad827..7eae5c2f5 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.ts @@ -8,21 +8,14 @@ import {FilterDropdown} from "../../models/filter-dropdown.model" templateUrl: "./filter-dropdown.component.html", styleUrls: ["./filter-dropdown.component.scss"] }) -export class FilterDropdownComponent implements OnInit { +export class FilterDropdownComponent { @Output() applyFilter = new EventEmitter() showInputs = false @Input() filterFg?: FormGroup - keywordType = KeywordType - @Input() - keywords?: FilterDropdown - - ngOnInit(): void { - this.filterFg?.patchValue(this.keywords ?? {}) - } onApplyFilter(): void { this.showInputs = !this.showInputs diff --git a/ui/src/app/shared/search-multi-select/search-multi-select.component.html b/ui/src/app/shared/search-multi-select/search-multi-select.component.html index a281992e0..dbeeca421 100644 --- a/ui/src/app/shared/search-multi-select/search-multi-select.component.html +++ b/ui/src/app/shared/search-multi-select/search-multi-select.component.html @@ -80,7 +80,7 @@
    -
    +
    {{result}}
    - +
    diff --git a/ui/src/app/table/filter-controls/filter-controls.component.ts b/ui/src/app/table/filter-controls/filter-controls.component.ts index fcd476a0c..3704bee30 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.ts +++ b/ui/src/app/table/filter-controls/filter-controls.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, OnInit, Output} from "@angular/core" +import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from "@angular/core" import {PublishStatus} from "../../PublishStatus"; import {FilterDropdown} from "../../models/filter-dropdown.model" import {FormBuilder, FormGroup} from "@angular/forms" @@ -8,7 +8,7 @@ import {FormBuilder, FormGroup} from "@angular/forms" templateUrl: "./filter-controls.component.html", styleUrls: ["./filter-controls.component.scss"] }) -export class FilterControlsComponent implements OnInit { +export class FilterControlsComponent implements OnInit, OnChanges { @Input() selectedFilters: Set = new Set() @Output() keywordsChanged: EventEmitter = new EventEmitter() @Output() filtersChanged: EventEmitter> = new EventEmitter>() @@ -20,12 +20,15 @@ export class FilterControlsComponent implements OnInit { protected formBuilder: FormBuilder ) { this.filterFg = this.configureFilterFg() - // this.keywords = this.filterFg.value } ngOnInit(): void { } + ngOnChanges(changes: SimpleChanges): void { + this.filterFg.patchValue(this.keywords ?? {}) + } + onFilterChange(status: PublishStatus, isChecked: boolean): void { if (isChecked) { this.selectedFilters.add(status) From b93456f1c3bc1f2b5ed787bcc3cc2f2779c07176 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 20 Feb 2023 17:00:29 -0600 Subject: [PATCH 094/150] Add remove event - Detect when a chip value was removed --- ui/src/app/shared/filter-chips/filter-chips.component.ts | 5 ++++- .../table/filter-controls/filter-controls.component.html | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.ts b/ui/src/app/shared/filter-chips/filter-chips.component.ts index 5a5ea1577..b62eba692 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.ts +++ b/ui/src/app/shared/filter-chips/filter-chips.component.ts @@ -1,4 +1,4 @@ -import {Component, Input} from "@angular/core" +import {Component, EventEmitter, Input, Output} from "@angular/core" import {FormControl} from "@angular/forms" @Component({ @@ -12,6 +12,8 @@ export class FilterChipsComponent { name?: string @Input() control?: FormControl + @Output() + remove: EventEmitter = new EventEmitter() onRemoveChip(chipText: string): void { const values = this.control?.value @@ -19,6 +21,7 @@ export class FilterChipsComponent { if (index >= 0) { values.splice(index, 1) this.control?.patchValue(values) + this.remove.emit(true) } } diff --git a/ui/src/app/table/filter-controls/filter-controls.component.html b/ui/src/app/table/filter-controls/filter-controls.component.html index 80d8f5738..e00477dcf 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.html +++ b/ui/src/app/table/filter-controls/filter-controls.component.html @@ -29,36 +29,43 @@

    Filters

    From b1d5fef0c4d7165cc1decb36040cad85230d613c Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Tue, 21 Feb 2023 09:48:32 -0600 Subject: [PATCH 095/150] trying nested queries --- .../edu/wgu/osmt/api/model/ApiSearch.kt | 31 ++++++++++-- .../edu/wgu/osmt/richskill/RichSkillDoc.kt | 2 +- .../edu/wgu/osmt/richskill/RichSkillEsRepo.kt | 48 ++++++------------- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt index 0fda59ff5..15892cdf0 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt @@ -65,16 +65,19 @@ data class ApiSkillListUpdate( @JsonInclude(JsonInclude.Include.ALWAYS) data class ApiAdvancedFilteredSearch( @JsonProperty("statuses") - val statuses: List? = null, + val statuses: Array? = null, - @JsonProperty("skillStatement") + @JsonProperty("statement") val skillStatement: String? = null, @JsonProperty("categories") - val categories: List? = null, + val categories: Array? = null, + + @JsonProperty("keywords") + val keywords: Array? = null, @JsonProperty("standards") - val standards: List? = null, + val standards: Array? = null, @JsonProperty("certifications") val certifications: List? = null, @@ -85,4 +88,22 @@ data class ApiAdvancedFilteredSearch( @JsonProperty("jobcodes") val jobCodes: List? = null -) \ No newline at end of file +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ApiAdvancedFilteredSearch + + if (statuses != null) { + if (other.statuses == null) return false + if (!statuses.contentEquals(other.statuses)) return false + } else if (other.statuses != null) return false + + return true + } + + override fun hashCode(): Int { + return statuses?.contentHashCode() ?: 0 + } +} \ No newline at end of file diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillDoc.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillDoc.kt index 90dfdd045..0601f22c9 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillDoc.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillDoc.kt @@ -115,7 +115,7 @@ data class RichSkillDoc( InnerField(suffix = "keyword", type = Keyword) ] ) - @get:JsonIgnore + @get:JsonProperty("standards") val standards: List = listOf(), @MultiField( diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt index 775b61b8f..2999fc8ec 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt @@ -79,7 +79,7 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear if (it.contains("\"")) { bq.must(simpleQueryStringQuery(it).field("${RichSkillDoc::name.name}.raw").defaultOperator(Operator.AND)) } else { - bq.must(QueryBuilders.matchBoolPrefixQuery(RichSkillDoc::name.name, it)) + bq.must(matchBoolPrefixQuery(RichSkillDoc::name.name, it)) } } category.nullIfEmpty()?.let { @@ -93,7 +93,7 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear if (it.contains("\"")) { bq.must(simpleQueryStringQuery(it).field("${RichSkillDoc::author.name}.raw").defaultOperator(Operator.AND)) } else { - bq.must(QueryBuilders.matchBoolPrefixQuery(RichSkillDoc::author.name, it)) + bq.must(matchBoolPrefixQuery(RichSkillDoc::author.name, it)) } } skillStatement.nullIfEmpty()?.let { @@ -102,7 +102,7 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear simpleQueryStringQuery(it).field("${RichSkillDoc::statement.name}.raw").defaultOperator(Operator.AND) ) } else { - bq.must(QueryBuilders.matchBoolPrefixQuery(RichSkillDoc::statement.name, it)) + bq.must(matchBoolPrefixQuery(RichSkillDoc::statement.name, it)) } } keywords?.map { @@ -112,7 +112,7 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear .defaultOperator(Operator.AND) ) } else { - bq.must(QueryBuilders.matchBoolPrefixQuery(RichSkillDoc::searchingKeywords.name, it)) + bq.must(matchBoolPrefixQuery(RichSkillDoc::searchingKeywords.name, it)) } } @@ -177,44 +177,24 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear override fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiAdvancedFilteredSearch) { with(filteredQuery) { - - statuses?.nullIfEmpty()?.let { - it.mapNotNull { value -> + skillStatement.nullIfEmpty()?.let { bq.must( - simpleQueryStringQuery(value).field("${RichSkillDoc::publishStatus.name}.keyword") + simpleQueryStringQuery(it).field("${RichSkillDoc::statement.name}.keyword") .defaultOperator(Operator.AND) ) - } - } - skillStatement.nullIfEmpty()?.let { - bq.must( - simpleQueryStringQuery(it).field("${RichSkillDoc::statement.name}.raw").defaultOperator(Operator.AND) - ) - } - standards?.let { it -> - it.mapNotNull { it.name }.map { s -> - bq.should(matchBoolPrefixQuery(RichSkillDoc::standards.name, s)) - } - } - certifications?.let { it -> - it.mapNotNull { it.name }.map { s -> - bq.should(matchBoolPrefixQuery(RichSkillDoc::certifications.name, s)) - } - } - alignments?.let { it -> - it.mapNotNull { it.name }.map { s -> - bq.should(matchBoolPrefixQuery(RichSkillDoc::alignments.name, s)) - } + } - jobCodes?.let { - it.mapNotNull { value -> - bq.must( - occupationQueries(value) + categories?.map { + bq.should( + simpleQueryStringQuery(it).field("${RichSkillDoc::category.name}.keyword") + .defaultOperator(Operator.AND) ) - } + } } + + } override fun richSkillPropertiesMultiMatch(query: String): BoolQueryBuilder { From 7d807515a2dee99d379374c36b2386f5dc722dcf Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Tue, 21 Feb 2023 10:33:43 -0600 Subject: [PATCH 096/150] correcting import --- ui/src/app/richskill/list/skills-list.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index eac5c90ef..42c0db6cd 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -1,4 +1,4 @@ -import {ApiSearch, PaginatedSkills} from "../service/rich-skill-search.service"; +import {ApiSearch, ApiSkillListUpdate, PaginatedSkills} from "../service/rich-skill-search.service"; import {ApiSkillSummary} from "../ApiSkillSummary"; import {checkArchived, determineFilters, PublishStatus} from "../../PublishStatus"; import {TableActionDefinition} from "../../table/skills-library-table/has-action-definitions"; From 540ec34bcecf606ee59c91d34751fc1313dd9421 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 21 Feb 2023 11:24:28 -0600 Subject: [PATCH 097/150] Fix merge --- ui/src/app/my-workspace/my-workspace.component.html | 1 - ui/src/app/richskill/list/skills-list.component.ts | 1 - 2 files changed, 2 deletions(-) delete mode 100644 ui/src/app/my-workspace/my-workspace.component.html diff --git a/ui/src/app/my-workspace/my-workspace.component.html b/ui/src/app/my-workspace/my-workspace.component.html deleted file mode 100644 index b64a93059..000000000 --- a/ui/src/app/my-workspace/my-workspace.component.html +++ /dev/null @@ -1 +0,0 @@ -

    my-workspace works!

    diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 42c0db6cd..0360ab36d 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -18,7 +18,6 @@ import {CollectionService} from "../../collection/service/collection.service" import {ApiCollection} from "../../collection/ApiCollection" import {CollectionPipe} from "../../pipes" import {FilterDropdown} from "../../models/filter-dropdown.model" -import {FormBuilder, FormGroup} from "@angular/forms" @Component({ selector: "app-skills-list", From c050fce072f0f44d765bff7bfb71a6acf5a37695 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 21 Feb 2023 12:37:06 -0600 Subject: [PATCH 098/150] Update tests - Update tests to match with the refactor. --- .../filter-chips.component.spec.ts | 6 ++-- .../filter-dropdown.component.spec.ts | 17 +++++------ .../search-multi-select.component.spec.ts | 17 +++++------ .../filter-controls.component.spec.ts | 30 +++++++++++++++++++ 4 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 ui/src/app/table/filter-controls/filter-controls.component.spec.ts diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts b/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts index 5b5bdf105..7766805ba 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts +++ b/ui/src/app/shared/filter-chips/filter-chips.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing" import { FilterChipsComponent } from "./filter-chips.component" +import {FormControl} from "@angular/forms" describe("FilterChipsComponent", () => { let component: FilterChipsComponent @@ -16,6 +17,7 @@ describe("FilterChipsComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(FilterChipsComponent) component = fixture.componentInstance + component.control = new FormControl([]) fixture.detectChanges() }) @@ -24,8 +26,8 @@ describe("FilterChipsComponent", () => { }) it("remove chip should remove and element from chips", () => { - component.keywords = ["chip1", "chip2"] + component.control?.patchValue(["chip1", "chip2"]) component.onRemoveChip("chip1") - expect(component.keywords.length).toBe(1) + expect(component.control?.value.length).toBe(1) }) }) diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.spec.ts b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.spec.ts index 9cb011311..0ef03a50c 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.spec.ts +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.spec.ts @@ -1,7 +1,8 @@ import { ComponentFixture, TestBed } from "@angular/core/testing" import { FilterDropdownComponent } from "./filter-dropdown.component" -import {FormsModule, ReactiveFormsModule} from "@angular/forms" +import {FilterControlsComponent} from "../../table/filter-controls/filter-controls.component" +import {ReactiveFormsModule} from "@angular/forms" describe("FilterComponent", () => { let component: FilterDropdownComponent @@ -9,7 +10,10 @@ describe("FilterComponent", () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ FilterDropdownComponent ], + declarations: [ + FilterDropdownComponent, + FilterControlsComponent + ], imports: [ ReactiveFormsModule ] @@ -20,6 +24,7 @@ describe("FilterComponent", () => { beforeEach(() => { fixture = TestBed.createComponent(FilterDropdownComponent) component = fixture.componentInstance + component.filterFg = TestBed.createComponent(FilterControlsComponent).componentInstance["configureFilterFg"]() fixture.detectChanges() }) @@ -27,14 +32,6 @@ describe("FilterComponent", () => { expect(component).toBeTruthy() }) - it("configure filter should works", () => { - component["configureFilterFg"]() - const value = component.filterFg.value - const properties = ["categories", "keywords", "standards", "certifications", "occupations", "employers"] - expect(value).toBeTruthy() - expect(properties.every(p => p in value)).toBeTrue() - }) - it("showInput should change", () => { const showInput = component.showInputs component.onApplyFilter() diff --git a/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts b/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts index 208d25f8a..b7328c6ec 100644 --- a/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts +++ b/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts @@ -29,8 +29,7 @@ describe("SearchMultiSelectComponent", () => { RouterTestingModule, ReactiveFormsModule ], - }) - .compileComponents() + }).compileComponents() const appConfig = TestBed.inject(AppConfig) AppConfig.settings = appConfig.defaultConfig() @@ -52,20 +51,20 @@ describe("SearchMultiSelectComponent", () => { expect(component.showResults).toBeTrue() }) - it("clear filed should clean input control", () => { + it("clear field should clean input control", () => { component.inputFc.patchValue("value") component.clearField() expect(component.inputFc.value.length).toBe(0) }) it("is result selected should be true", () => { - component.internalSelectedResults = ["value1", "value2"] + component.control?.patchValue(["value1", "value2"]) const isSelected = component.isResultSelected("value1") expect(isSelected).toBeTrue() }) it("is result selected should be false", () => { - component.internalSelectedResults = ["value1", "value2"] + component.control?.patchValue(["value1", "value2"]) const isSelected = component.isResultSelected("value3") expect(isSelected).toBeFalse() }) @@ -86,14 +85,14 @@ describe("SearchMultiSelectComponent", () => { }) it("select result should add value in internal result", () => { - component.internalSelectedResults = ["value1"] + component.control?.patchValue(["value1"]) component.selectResult("value2") - expect(component.internalSelectedResults.length).toBe(2) + expect(component.control?.value?.length).toBe(2) }) it("select result should remove value in internal result", () => { - component.internalSelectedResults = ["value1", "value2"] + component.control?.patchValue(["value1", "value2"]) component.selectResult("value2") - expect(component.internalSelectedResults.length).toBe(1) + expect(component.control?.value?.length).toBe(1) }) }) diff --git a/ui/src/app/table/filter-controls/filter-controls.component.spec.ts b/ui/src/app/table/filter-controls/filter-controls.component.spec.ts new file mode 100644 index 000000000..860de480d --- /dev/null +++ b/ui/src/app/table/filter-controls/filter-controls.component.spec.ts @@ -0,0 +1,30 @@ +import {FilterControlsComponent} from "./filter-controls.component" +import {ComponentFixture, TestBed} from "@angular/core/testing" + +describe("FilterControlsComponent", () => { + let component: FilterControlsComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [FilterControlsComponent], + imports: [], + providers: [] + }).compileComponents() + }) + + beforeEach(() => { + fixture = TestBed.createComponent(FilterControlsComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it("configure filter should works", () => { + component["configureFilterFg"]() + const value = component.filterFg.value + const properties = ["categories", "keywords", "standards", "certifications", "occupations", "employers"] + expect(value).toBeTruthy() + expect(properties.every(p => p in value)).toBeTrue() + }) + +}) From a9839f8ba9950d98efee777b96c50ce02553413e Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Tue, 21 Feb 2023 15:39:50 -0600 Subject: [PATCH 099/150] Fix tests - Now tests are running. --- .../search-multi-select.component.spec.ts | 4 ++-- .../table/filter-controls/filter-controls.component.spec.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts b/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts index b7328c6ec..b95945cf9 100644 --- a/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts +++ b/ui/src/app/shared/search-multi-select/search-multi-select.component.spec.ts @@ -2,7 +2,6 @@ import {ComponentFixture, TestBed} from "@angular/core/testing" import {SearchMultiSelectComponent} from "./search-multi-select.component" import {KeywordSearchService} from "../../richskill/service/keyword-search.service" -import {HttpClientModule} from "@angular/common/http" import {AuthService} from "../../auth/auth-service" import {AuthServiceStub} from "../../../../test/resource/mock-stubs" import {RouterTestingModule} from "@angular/router/testing" @@ -11,6 +10,7 @@ import {AppConfig} from "../../app.config" import {createMockApiNamedReference, createMockJobcode} from "../../../../test/resource/mock-data" import {of} from "rxjs" import {KeywordType} from "../../richskill/ApiSkill" +import {HttpClientTestingModule} from "@angular/common/http/testing" describe("SearchMultiSelectComponent", () => { let component: SearchMultiSelectComponent @@ -25,7 +25,7 @@ describe("SearchMultiSelectComponent", () => { {provide: AuthService, useClass: AuthServiceStub}, ], imports: [ - HttpClientModule, + HttpClientTestingModule, RouterTestingModule, ReactiveFormsModule ], diff --git a/ui/src/app/table/filter-controls/filter-controls.component.spec.ts b/ui/src/app/table/filter-controls/filter-controls.component.spec.ts index 860de480d..b27658d81 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.spec.ts +++ b/ui/src/app/table/filter-controls/filter-controls.component.spec.ts @@ -1,5 +1,6 @@ import {FilterControlsComponent} from "./filter-controls.component" import {ComponentFixture, TestBed} from "@angular/core/testing" +import {FormBuilder} from "@angular/forms" describe("FilterControlsComponent", () => { let component: FilterControlsComponent @@ -9,7 +10,9 @@ describe("FilterControlsComponent", () => { await TestBed.configureTestingModule({ declarations: [FilterControlsComponent], imports: [], - providers: [] + providers: [ + FormBuilder + ] }).compileComponents() }) From d0b0c0b5be52e3b232dc8b65b6cd83f0d048b44f Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 22 Feb 2023 08:28:18 -0600 Subject: [PATCH 100/150] trying nested queries attempt #2 using disjuctionQuery --- .../edu/wgu/osmt/api/model/ApiSearch.kt | 17 +++- .../edu/wgu/osmt/richskill/RichSkillEsRepo.kt | 97 +++++++++++++++++-- .../config/application-dev.properties | 2 +- 3 files changed, 103 insertions(+), 13 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt index 15892cdf0..190d09fe1 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt @@ -80,13 +80,24 @@ data class ApiAdvancedFilteredSearch( val standards: Array? = null, @JsonProperty("certifications") - val certifications: List? = null, + val certifications: Array? = null, @JsonProperty("alignments") - val alignments: List? = null, + val alignments: Array? = null, @JsonProperty("jobcodes") - val jobCodes: List? = null + val jobCodes: Array? = null, + + @JsonProperty("employers") + val employers: Array? = null, + + @JsonProperty("authors") + val authors: Array? = null, + + @JsonProperty("occupations") + val occupations: Array? = null, + + ) { override fun equals(other: Any?): Boolean { diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt index 2999fc8ec..7228df233 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt @@ -70,6 +70,24 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear ) } + fun buildNestedQuery(path: String, field: String, queryParams: Array) : BoolQueryBuilder { + val disjunctionQuery = disMaxQuery() + var queries = ArrayList() + queryParams.let { + it.mapNotNull {param -> + queries.add ( + prefixQuery(path+field, param) + ) + } + + } + + disjunctionQuery.innerQueries().addAll(queries) + + return boolQuery().must(existsQuery(path+field)).must(disjunctionQuery) + } + + // Query clauses for Rich Skill properties override fun generateBoolQueriesFromApiSearch(bq: BoolQueryBuilder, advancedQuery: ApiAdvancedSearch) { with(advancedQuery) { @@ -177,21 +195,82 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear override fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiAdvancedFilteredSearch) { with(filteredQuery) { - skillStatement.nullIfEmpty()?.let { - bq.must( - simpleQueryStringQuery(it).field("${RichSkillDoc::statement.name}.keyword") - .defaultOperator(Operator.AND) - ) - } - - categories?.map { + statuses?.let { + it.mapNotNull {status -> bq.should( - simpleQueryStringQuery(it).field("${RichSkillDoc::category.name}.keyword") + simpleQueryStringQuery(status).field("${RichSkillDoc::publishStatus.name}.keyword") .defaultOperator(Operator.AND) ) + } + } + + categories?. let { + buildNestedQuery(RichSkillDoc::category.name, "${RichSkillDoc::category.name}.keyword", it) } +// keywords?. let { +// it. +// mapNotNull { +// bq.should( +// simpleQueryStringQuery(it).field("${RichSkillDoc::searchingKeywords.name}.keyword") +// .defaultOperator(Operator.AND) +// ) +// } +// } +// standards?. let { +// it. +// mapNotNull { +// bq.should( +// simpleQueryStringQuery(it).field("${RichSkillDoc::standards.name}.keyword") +// .defaultOperator(Operator.AND) +// ) +// } +// } +// certifications?. let { +// it. +// mapNotNull { +// bq.should( +// simpleQueryStringQuery(it).field("${RichSkillDoc::certifications.name}.keyword") +// .defaultOperator(Operator.AND) +// ) +// } +// } +// alignments?. let { +// it. +// mapNotNull { +// bq.should( +// simpleQueryStringQuery(it).field("${RichSkillDoc::alignments.name}.keyword") +// .defaultOperator(Operator.AND) +// ) +// } +// } +// authors?. let { +// it. +// mapNotNull { +// bq.should( +// simpleQueryStringQuery(it).field("${RichSkillDoc::author.name}.keyword") +// .defaultOperator(Operator.AND) +// ) +// } +// } +// occupations?.let { +// it.mapNotNull { value -> +// bq.must( +// occupationQueries(value) +// ) +// } +// } +// jobCodes?.let { +// it.mapNotNull { value -> +// bq.must( +// occupationQueries(value) +// ) +// } +// } + + + } diff --git a/api/src/main/resources/config/application-dev.properties b/api/src/main/resources/config/application-dev.properties index 412ede621..088abc088 100644 --- a/api/src/main/resources/config/application-dev.properties +++ b/api/src/main/resources/config/application-dev.properties @@ -13,6 +13,6 @@ app.security.cors.allowedOrigins=${app.baseUrl},${app.frontendUrl} management.endpoint.health.show-details=always # Uncomment to see elasticsearch queries -#logging.level.org.springframework.data.elasticsearch.client.WIRE=trace +logging.level.org.springframework.data.elasticsearch.client.WIRE=trace spring.flyway.enabled=true From 9e6c3931b9ebfa66a2c928bf7cdb48b80bcbd18b Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 22 Feb 2023 10:29:46 -0600 Subject: [PATCH 101/150] Implementing nested query with categories --- .../kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt index 7228df233..fbb6bf6ca 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt @@ -70,13 +70,13 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear ) } - fun buildNestedQuery(path: String, field: String, queryParams: Array) : BoolQueryBuilder { + fun buildNestedQuery(path: String?=null, queryParams: Array) : BoolQueryBuilder { val disjunctionQuery = disMaxQuery() var queries = ArrayList() queryParams.let { it.mapNotNull {param -> queries.add ( - prefixQuery(path+field, param) + prefixQuery(path + ".keyword", param) ) } @@ -84,7 +84,9 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear disjunctionQuery.innerQueries().addAll(queries) - return boolQuery().must(existsQuery(path+field)).must(disjunctionQuery) + val result = boolQuery().must(existsQuery(path + ".keyword")).must(disjunctionQuery) + + return result } @@ -207,7 +209,7 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear } categories?. let { - buildNestedQuery(RichSkillDoc::category.name, "${RichSkillDoc::category.name}.keyword", it) + bq.should(buildNestedQuery(RichSkillDoc::category.name, it)) } // keywords?. let { // it. From 648c4177a690d5c8c14ad86881eacd86b922f9ec Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 23 Feb 2023 10:34:16 -0600 Subject: [PATCH 102/150] Add author & ApiAdvancedFilteredSearch - Add author in multi select and chips. - Add ApiAdvancedFilteredSearch to send request. --- ui/src/app/models/filter-dropdown.model.ts | 1 + .../app/richskill/list/skills-list.component.ts | 3 ++- .../service/rich-skill-search.service.ts | 15 +++++++++++++++ .../filter-dropdown.component.html | 7 ++++++- .../filter-controls.component.html | 6 ++++++ .../filter-controls/filter-controls.component.ts | 3 ++- 6 files changed, 32 insertions(+), 3 deletions(-) diff --git a/ui/src/app/models/filter-dropdown.model.ts b/ui/src/app/models/filter-dropdown.model.ts index 1f3ae54ae..a0b9dbc05 100644 --- a/ui/src/app/models/filter-dropdown.model.ts +++ b/ui/src/app/models/filter-dropdown.model.ts @@ -6,4 +6,5 @@ export interface FilterDropdown { certifications: string[] occupations: string[] employers: string[] + authors: string[] } diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 0360ab36d..4d156af92 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -44,7 +44,8 @@ export class SkillsListComponent extends QuickLinksHelper { alignments: [], keywords: [], occupations: [], - standards: [] + standards: [], + authors: [] } selectedSkills?: ApiSkillSummary[] skillsSaved?: Observable diff --git a/ui/src/app/richskill/service/rich-skill-search.service.ts b/ui/src/app/richskill/service/rich-skill-search.service.ts index 1a9527c3c..d3400a8a0 100644 --- a/ui/src/app/richskill/service/rich-skill-search.service.ts +++ b/ui/src/app/richskill/service/rich-skill-search.service.ts @@ -26,6 +26,21 @@ export class ApiSearch implements ISearch { } } +export interface ApiAdvancedFilteredSearch { + standards?: string[] + authors?: string[] + occupations?: string[] + certifications?: string[] + jobcodes?: string[] + categories?: string[] + employers?: string[] + statuses?: string[] + skillStatement?: string + keywords?: string[] + alignments?: string[] + statement?: string +} + export class ApiAdvancedSearch { skillName?: string collectionName?: string diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html index ffd6d60fe..665a9a454 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html @@ -45,9 +45,14 @@

    name="occupations"> + + diff --git a/ui/src/app/table/filter-controls/filter-controls.component.html b/ui/src/app/table/filter-controls/filter-controls.component.html index e00477dcf..ec4e7869a 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.html +++ b/ui/src/app/table/filter-controls/filter-controls.component.html @@ -68,5 +68,11 @@

    Filters

    (remove)="keywordsChanged.emit(filterFg.value)" *ngIf="filterFg?.get('employers')?.value?.length > 0"> + + diff --git a/ui/src/app/table/filter-controls/filter-controls.component.ts b/ui/src/app/table/filter-controls/filter-controls.component.ts index 3704bee30..41c80d566 100644 --- a/ui/src/app/table/filter-controls/filter-controls.component.ts +++ b/ui/src/app/table/filter-controls/filter-controls.component.ts @@ -67,7 +67,8 @@ export class FilterControlsComponent implements OnInit, OnChanges { alignments: [], certifications: [], occupations: [], - employers: [] + employers: [], + authors: [] }) } From 900e175c63497001689e81ea62b5be3c204f6f4e Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 23 Feb 2023 10:41:48 -0600 Subject: [PATCH 103/150] Clean code - Remove unused properties and slash comments. --- ui/src/app/shared/filter-chips/filter-chips.component.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.scss b/ui/src/app/shared/filter-chips/filter-chips.component.scss index f560dcf79..b9ebea67f 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.scss +++ b/ui/src/app/shared/filter-chips/filter-chips.component.scss @@ -2,7 +2,6 @@ display: flex; flex-wrap: wrap; border: solid gray; - // border-radius: 40px; padding: 10px 5px 5px 5px; width: 95%; } @@ -13,11 +12,9 @@ margin-left:10px; color:white; background: #1f1f1f; - // border-radius:10px; padding:2px 10px; } -// .chip { width: fit-content; padding: 0 10px; From 077bcf3582fd720057c70d4522716094464f152b Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Thu, 23 Feb 2023 17:02:09 -0600 Subject: [PATCH 104/150] Implementing queries in ESrepo layer for keywords, standards, aligments, employers and authors. --- .../edu/wgu/osmt/richskill/RichSkillEsRepo.kt | 140 ++++++++---------- .../config/application-dev.properties | 2 +- 2 files changed, 65 insertions(+), 77 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt index fbb6bf6ca..51605e29f 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt @@ -15,6 +15,7 @@ import edu.wgu.osmt.nullIfEmpty import org.apache.lucene.search.join.ScoreMode import org.elasticsearch.index.query.* import org.elasticsearch.index.query.QueryBuilders.* +import org.elasticsearch.script.Script import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Configuration import org.springframework.data.domain.Page @@ -70,23 +71,21 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear ) } - fun buildNestedQuery(path: String?=null, queryParams: Array) : BoolQueryBuilder { + fun buildNestedQueries(path: String?=null, queryParams: Array) : BoolQueryBuilder { val disjunctionQuery = disMaxQuery() - var queries = ArrayList() + val queries = ArrayList() + queryParams.let { - it.mapNotNull {param -> - queries.add ( + it.map { param -> + queries.add( prefixQuery(path + ".keyword", param) ) } } - disjunctionQuery.innerQueries().addAll(queries) - val result = boolQuery().must(existsQuery(path + ".keyword")).must(disjunctionQuery) - - return result + return boolQuery().must(existsQuery(path + ".keyword")).must(disjunctionQuery) } @@ -196,86 +195,75 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear } override fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiAdvancedFilteredSearch) { + + with(filteredQuery) { - statuses?.let { - it.mapNotNull {status -> - bq.should( - simpleQueryStringQuery(status).field("${RichSkillDoc::publishStatus.name}.keyword") - .defaultOperator(Operator.AND) + categories?. let { + bq.must(buildNestedQueries(RichSkillDoc::category.name, it)) + } + keywords?. let { + it.mapNotNull { + bq.must( + TermsSetQueryBuilder( + "${RichSkillDoc::searchingKeywords.name}.keyword", keywords.toList() + ) + .setMinimumShouldMatchScript(Script(keywords.size.toString())) ) } } + standards?. let { + it.mapNotNull { + bq.must( + TermsSetQueryBuilder( + "${RichSkillDoc::standards.name}.keyword", standards.toList() + ) + .setMinimumShouldMatchScript(Script(standards.size.toString())) + ) - categories?. let { - bq.should(buildNestedQuery(RichSkillDoc::category.name, it)) + } } -// keywords?. let { -// it. -// mapNotNull { -// bq.should( -// simpleQueryStringQuery(it).field("${RichSkillDoc::searchingKeywords.name}.keyword") -// .defaultOperator(Operator.AND) -// ) -// } -// } -// standards?. let { -// it. -// mapNotNull { -// bq.should( -// simpleQueryStringQuery(it).field("${RichSkillDoc::standards.name}.keyword") -// .defaultOperator(Operator.AND) -// ) -// } -// } -// certifications?. let { -// it. -// mapNotNull { -// bq.should( -// simpleQueryStringQuery(it).field("${RichSkillDoc::certifications.name}.keyword") -// .defaultOperator(Operator.AND) -// ) -// } -// } -// alignments?. let { -// it. -// mapNotNull { -// bq.should( -// simpleQueryStringQuery(it).field("${RichSkillDoc::alignments.name}.keyword") -// .defaultOperator(Operator.AND) -// ) -// } -// } -// authors?. let { -// it. -// mapNotNull { -// bq.should( -// simpleQueryStringQuery(it).field("${RichSkillDoc::author.name}.keyword") -// .defaultOperator(Operator.AND) -// ) -// } -// } -// occupations?.let { -// it.mapNotNull { value -> -// bq.must( -// occupationQueries(value) -// ) -// } -// } -// jobCodes?.let { -// it.mapNotNull { value -> -// bq.must( -// occupationQueries(value) -// ) -// } -// } + certifications?. let { + it.mapNotNull { + bq.must( + TermsSetQueryBuilder( + "${RichSkillDoc::certifications.name}.keyword", certifications.toList() + ) + .setMinimumShouldMatchScript(Script(certifications.size.toString())) + ) + } + } + alignments?. let { + it.mapNotNull { + bq.must( + TermsSetQueryBuilder( + "${RichSkillDoc::alignments.name}.keyword", alignments.toList() + ) + .setMinimumShouldMatchScript(Script(alignments.size.toString())) + ) + } + } + employers?. let { + bq.must(buildNestedQueries(RichSkillDoc::employers.name, it)) + } + authors?. let { + bq.must(buildNestedQueries(RichSkillDoc::author.name, it)) + } + occupations?. let { + it.mapNotNull { + bq.must( + TermsSetQueryBuilder( + "${RichSkillDoc::jobCodes.name}.keyword", occupations.toList() + ) + .setMinimumShouldMatchScript(Script(occupations.size.toString())) + ) + } + } } - - } override fun richSkillPropertiesMultiMatch(query: String): BoolQueryBuilder { diff --git a/api/src/main/resources/config/application-dev.properties b/api/src/main/resources/config/application-dev.properties index 088abc088..412ede621 100644 --- a/api/src/main/resources/config/application-dev.properties +++ b/api/src/main/resources/config/application-dev.properties @@ -13,6 +13,6 @@ app.security.cors.allowedOrigins=${app.baseUrl},${app.frontendUrl} management.endpoint.health.show-details=always # Uncomment to see elasticsearch queries -logging.level.org.springframework.data.elasticsearch.client.WIRE=trace +#logging.level.org.springframework.data.elasticsearch.client.WIRE=trace spring.flyway.enabled=true From 653b138d62b844afdd4ad14d85d41e19f1be6cd7 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 24 Feb 2023 08:09:21 -0600 Subject: [PATCH 105/150] Adding JobCodes to nested query --- .../kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt index 51605e29f..093b0bf41 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt @@ -252,15 +252,11 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear authors?. let { bq.must(buildNestedQueries(RichSkillDoc::author.name, it)) } - occupations?. let { - it.mapNotNull { + occupations?.let { + it.mapNotNull { value -> bq.must( - TermsSetQueryBuilder( - "${RichSkillDoc::jobCodes.name}.keyword", occupations.toList() - ) - .setMinimumShouldMatchScript(Script(occupations.size.toString())) + occupationQueries(value) ) - } } } From 59ccbf411a70fa18d21a355ffc20275dfb243b1d Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 24 Feb 2023 09:00:47 -0600 Subject: [PATCH 106/150] Adding draft Endpoint to use post in skills filtered --- .../main/kotlin/edu/wgu/osmt/RoutePaths.kt | 1 + .../wgu/osmt/richskill/RichSkillController.kt | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt b/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt index bc03a1cd4..ae0088a78 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/RoutePaths.kt @@ -13,6 +13,7 @@ object RoutePaths { const val SKILLS_PATH = "$API/skills" const val SKILLS_LIST = SKILLS_PATH const val SKILLS_CREATE = SKILLS_PATH + const val SKILLS_FILTER = "$SKILLS_PATH/filter" const val SKILL_PUBLISH = "$SKILLS_PATH/publish" const val SKILL_DETAIL = "$SKILLS_PATH/{uuid}" const val SKILL_UPDATE = "$SKILL_DETAIL/update" diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt index 3bd85c727..e1b582e80 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt @@ -7,12 +7,14 @@ import edu.wgu.osmt.api.model.ApiSearch import edu.wgu.osmt.api.model.ApiSkill import edu.wgu.osmt.api.model.ApiSkillUpdate import edu.wgu.osmt.api.model.SkillSortEnum +import edu.wgu.osmt.api.model.SortOrder import edu.wgu.osmt.auditlog.AuditLog import edu.wgu.osmt.auditlog.AuditLogRepository import edu.wgu.osmt.auditlog.AuditLogSortEnum import edu.wgu.osmt.config.AppConfig import edu.wgu.osmt.db.PublishStatus import edu.wgu.osmt.elasticsearch.OffsetPageable +import edu.wgu.osmt.elasticsearch.PaginatedLinks import edu.wgu.osmt.keyword.KeywordDao import edu.wgu.osmt.security.OAuthHelper import edu.wgu.osmt.task.AppliesToType @@ -23,6 +25,7 @@ import edu.wgu.osmt.task.PublishTask import edu.wgu.osmt.task.Task import edu.wgu.osmt.task.TaskMessageService import edu.wgu.osmt.task.TaskResult +import org.apache.commons.lang3.StringUtils import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.HttpEntity import org.springframework.http.HttpHeaders @@ -76,6 +79,51 @@ class RichSkillController @Autowired constructor( return super.allPaginated(uriComponentsBuilder, size, from, status, sort, user) } + @PostMapping(RoutePaths.SKILLS_FILTER, produces = [MediaType.APPLICATION_JSON_VALUE]) + @ResponseBody + fun allPaginatedWithFilters( + uriComponentsBuilder: UriComponentsBuilder, + size: Int, + from: Int, + status: Array, + @RequestBody apiSearch: ApiSearch, + sort: String?, + @AuthenticationPrincipal user: Jwt? + ): HttpEntity> { + + val publishStatuses = status.mapNotNull { + val status = PublishStatus.forApiValue(it) + if (user == null && (status == PublishStatus.Deleted || status == PublishStatus.Draft)) null else status + }.toSet() + val sortEnum: SortOrder = sortOrderCompanion.forValueOrDefault(sort) + val pageable = OffsetPageable(from, size, sortEnum.sort) + val searchHits = richSkillEsRepo.byApiSearch( + apiSearch, + publishStatuses, + pageable, + StringUtils.EMPTY + ) + val countAllFiltered: Long = searchHits.totalHits + val responseHeaders = HttpHeaders() + responseHeaders.add("X-Total-Count", countAllFiltered.toString()) + + uriComponentsBuilder + .path(allPaginatedPath) + .queryParam(RoutePaths.QueryParams.FROM, from) + .queryParam(RoutePaths.QueryParams.SIZE, size) + .queryParam(RoutePaths.QueryParams.SORT, sort) + .queryParam(RoutePaths.QueryParams.STATUS, status.joinToString(",").toLowerCase()) + + PaginatedLinks( + pageable, + searchHits.totalHits.toInt(), + uriComponentsBuilder + ).addToHeaders(responseHeaders) + + return ResponseEntity.status(200).headers(responseHeaders) + .body(searchHits.map { it.content }.toList()) + } + @PostMapping(RoutePaths.SKILLS_CREATE, produces = [MediaType.APPLICATION_JSON_VALUE]) @ResponseBody fun createSkills( From 18139c5ec1a1fc42e87dd960aa01cad5620191c6 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 24 Feb 2023 10:42:49 -0600 Subject: [PATCH 107/150] Refactoring Request Body Object --- .../edu/wgu/osmt/api/model/ApiSearch.kt | 58 ++++--------------- .../edu/wgu/osmt/richskill/RichSkillEsRepo.kt | 8 +-- 2 files changed, 16 insertions(+), 50 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt index 190d09fe1..18d2ce809 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt @@ -12,7 +12,7 @@ data class ApiSearch( val advanced: ApiAdvancedSearch? = null, @JsonProperty("filtered") - val filtered: ApiAdvancedFilteredSearch? = null, + val filtered: ApiFilteredSearch? = null, @JsonProperty("uuids") val uuids: List? = null @@ -63,58 +63,24 @@ data class ApiSkillListUpdate( ) @JsonInclude(JsonInclude.Include.ALWAYS) -data class ApiAdvancedFilteredSearch( - @JsonProperty("statuses") - val statuses: Array? = null, +data class ApiFilteredSearch( - @JsonProperty("statement") - val skillStatement: String? = null, - - @JsonProperty("categories") - val categories: Array? = null, + val categories: List? = null, - @JsonProperty("keywords") - val keywords: Array? = null, + val keywords: List? = null, - @JsonProperty("standards") - val standards: Array? = null, + val standards: List? = null, - @JsonProperty("certifications") - val certifications: Array? = null, + val certifications: List? = null, - @JsonProperty("alignments") - val alignments: Array? = null, + val alignments: List? = null, @JsonProperty("jobcodes") - val jobCodes: Array? = null, - - @JsonProperty("employers") - val employers: Array? = null, - - @JsonProperty("authors") - val authors: Array? = null, - - @JsonProperty("occupations") - val occupations: Array? = null, - - - -) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as ApiAdvancedFilteredSearch + val jobCodes: List? = null, - if (statuses != null) { - if (other.statuses == null) return false - if (!statuses.contentEquals(other.statuses)) return false - } else if (other.statuses != null) return false + val employers: List? = null, - return true - } + val authors: List? = null, - override fun hashCode(): Int { - return statuses?.contentHashCode() ?: 0 - } -} \ No newline at end of file + val occupations: List? = null +) \ No newline at end of file diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt index 093b0bf41..dd4e040e5 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt @@ -1,8 +1,8 @@ package edu.wgu.osmt.richskill import edu.wgu.osmt.PaginationDefaults -import edu.wgu.osmt.api.model.ApiAdvancedFilteredSearch import edu.wgu.osmt.api.model.ApiAdvancedSearch +import edu.wgu.osmt.api.model.ApiFilteredSearch import edu.wgu.osmt.api.model.ApiSearch import edu.wgu.osmt.api.model.ApiSimilaritySearch import edu.wgu.osmt.config.INDEX_RICHSKILL_DOC @@ -33,7 +33,7 @@ const val collectionsUuid = "collections.uuid" interface CustomRichSkillQueries : FindsAllByPublishStatus { fun generateBoolQueriesFromApiSearch(bq: BoolQueryBuilder, advancedQuery: ApiAdvancedSearch) - fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiAdvancedFilteredSearch) + fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiFilteredSearch) fun richSkillPropertiesMultiMatch(query: String): BoolQueryBuilder fun byApiSearch( apiSearch: ApiSearch, @@ -71,7 +71,7 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear ) } - fun buildNestedQueries(path: String?=null, queryParams: Array) : BoolQueryBuilder { + fun buildNestedQueries(path: String?=null, queryParams: List) : BoolQueryBuilder { val disjunctionQuery = disMaxQuery() val queries = ArrayList() @@ -194,7 +194,7 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear } } - override fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiAdvancedFilteredSearch) { + override fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiFilteredSearch) { with(filteredQuery) { From 931f4b8e1ef64ae1b72ef45c81818defd9dbf2cf Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Fri, 24 Feb 2023 11:54:13 -0600 Subject: [PATCH 108/150] Reverting ApiFilteredSearch naming back for it to be deserialized properly --- api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt index 18d2ce809..c29536470 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/api/model/ApiSearch.kt @@ -65,22 +65,30 @@ data class ApiSkillListUpdate( @JsonInclude(JsonInclude.Include.ALWAYS) data class ApiFilteredSearch( + @JsonProperty("categories") val categories: List? = null, + @JsonProperty("keywords") val keywords: List? = null, + @JsonProperty("standards") val standards: List? = null, + @JsonProperty("certifications") val certifications: List? = null, + @JsonProperty("alignments") val alignments: List? = null, @JsonProperty("jobcodes") val jobCodes: List? = null, + @JsonProperty("employers") val employers: List? = null, + @JsonProperty("authors") val authors: List? = null, + @JsonProperty("occupations") val occupations: List? = null ) \ No newline at end of file From 51c935af3a95828bba358d857d57d16df3c537e4 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:52:40 -0600 Subject: [PATCH 109/150] Add ApiAdvancedFilteredSearch in request - Request is now using ApiAdvancedFilteredSearch. - Refactor code to use ApiAdvancedFilteredSearch. --- .../richskill/library/rich-skills-library.component.ts | 6 +++--- ui/src/app/richskill/service/rich-skill-search.service.ts | 8 ++++++-- ui/src/app/richskill/service/rich-skill.service.ts | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ui/src/app/richskill/library/rich-skills-library.component.ts b/ui/src/app/richskill/library/rich-skills-library.component.ts index 4bd92b184..d5c1966ed 100644 --- a/ui/src/app/richskill/library/rich-skills-library.component.ts +++ b/ui/src/app/richskill/library/rich-skills-library.component.ts @@ -2,7 +2,7 @@ import {Component, OnInit} from "@angular/core" import {RichSkillService} from "../service/rich-skill.service" import {SkillsListComponent} from "../list/skills-list.component" import {ToastService} from "../../toast/toast.service" -import {PaginatedSkills} from "../service/rich-skill-search.service" +import {ApiSearch, PaginatedSkills} from "../service/rich-skill-search.service" import {Router} from "@angular/router" import {determineFilters} from "../../PublishStatus" import {Title} from "@angular/platform-browser" @@ -38,8 +38,8 @@ export class RichSkillsLibraryComponent extends SkillsListComponent implements O this.setResults(new PaginatedSkills([], 0)) return } - - this.resultsLoaded = this.richSkillService.getSkills(this.size, this.from, determineFilters(this.selectedFilters), this.columnSort) + const apiSearch = new ApiSearch({filtered: {statuses: this.selectedFilters}}) + this.resultsLoaded = this.richSkillService.getSkills(this.size, this.from, apiSearch, this.columnSort) this.resultsLoaded.subscribe((results) => { this.setResults(results) }) diff --git a/ui/src/app/richskill/service/rich-skill-search.service.ts b/ui/src/app/richskill/service/rich-skill-search.service.ts index d3400a8a0..94ec4e756 100644 --- a/ui/src/app/richskill/service/rich-skill-search.service.ts +++ b/ui/src/app/richskill/service/rich-skill-search.service.ts @@ -1,21 +1,25 @@ import {INamedReference} from "../ApiSkill" import {ApiCollectionSummary, ApiSkillSummary} from "../ApiSkillSummary" +import {PublishStatus} from "../../PublishStatus" export interface ISearch { query?: string advanced?: ApiAdvancedSearch + filtered?: ApiAdvancedFilteredSearch uuids?: string[] } export class ApiSearch implements ISearch { query?: string advanced?: ApiAdvancedSearch + filtered?: ApiAdvancedFilteredSearch uuids?: string[] - constructor({query, advanced, uuids}: ISearch) { + constructor({query, advanced, uuids, filtered}: ISearch) { this.query = query this.advanced = advanced this.uuids = uuids + this.filtered = filtered } advancedMatchingQuery(): string[] { @@ -34,7 +38,7 @@ export interface ApiAdvancedFilteredSearch { jobcodes?: string[] categories?: string[] employers?: string[] - statuses?: string[] + statuses?: Set skillStatement?: string keywords?: string[] alignments?: string[] diff --git a/ui/src/app/richskill/service/rich-skill.service.ts b/ui/src/app/richskill/service/rich-skill.service.ts index 1f43ab985..5e812f3d2 100644 --- a/ui/src/app/richskill/service/rich-skill.service.ts +++ b/ui/src/app/richskill/service/rich-skill.service.ts @@ -29,11 +29,11 @@ export class RichSkillService extends AbstractService { getSkills( size: number = 50, from: number = 0, - filterByStatuses: Set | undefined, + apiSearch: ApiSearch, sort: ApiSortOrder | undefined, ): Observable { - const params = this.buildTableParams(size, from, filterByStatuses, sort) + const params = this.buildTableParams(size, from, apiSearch.filtered?.statuses, sort) return this.get({ path: `${this.serviceUrl}`, params, From 191dd705fa27820b799db7da6661483d2f17f49d Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Thu, 23 Feb 2023 17:26:22 -0600 Subject: [PATCH 110/150] Short imports - Add @shared in paths tsconfig.base.json. --- ui/src/app/app.module.ts | 2 +- ui/src/app/shared/index.ts | 3 +++ ui/src/app/shared/shared.module.ts | 8 +++++--- ui/tsconfig.base.json | 5 +++++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 ui/src/app/shared/index.ts diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 32a2d0978..42ddb2e1a 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -100,7 +100,7 @@ import {LibraryExportComponent} from "./navigation/libraryexport.component" import {MyWorkspaceComponent} from "./my-workspace/my-workspace.component" import {CollectionPipe} from "./pipes" import { ConvertToCollectionComponent } from "./my-workspace/convert-to-collection/convert-to-collection.component" -import {SharedModule} from "./shared/shared.module" +import {SharedModule} from "@shared/shared.module" export function initializeApp( appConfig: AppConfig, diff --git a/ui/src/app/shared/index.ts b/ui/src/app/shared/index.ts new file mode 100644 index 000000000..69ab6847f --- /dev/null +++ b/ui/src/app/shared/index.ts @@ -0,0 +1,3 @@ +export * from "./filter-chips/filter-chips.component" +export * from "./filter-drop-down/filter-dropdown.component" +export * from "./search-multi-select/search-multi-select.component" diff --git a/ui/src/app/shared/shared.module.ts b/ui/src/app/shared/shared.module.ts index 2e67ba989..1b4bb4368 100644 --- a/ui/src/app/shared/shared.module.ts +++ b/ui/src/app/shared/shared.module.ts @@ -1,9 +1,11 @@ import { NgModule } from "@angular/core" import { CommonModule } from "@angular/common" import { FormsModule, ReactiveFormsModule } from "@angular/forms" -import { FilterChipsComponent } from "./filter-chips/filter-chips.component" -import { FilterDropdownComponent } from "./filter-drop-down/filter-dropdown.component" -import { SearchMultiSelectComponent } from "./search-multi-select/search-multi-select.component" +import { + FilterChipsComponent, + FilterDropdownComponent, + SearchMultiSelectComponent +} from "@shared/." @NgModule({ declarations: [ diff --git a/ui/tsconfig.base.json b/ui/tsconfig.base.json index d06a13c13..9eefb45c5 100644 --- a/ui/tsconfig.base.json +++ b/ui/tsconfig.base.json @@ -14,6 +14,11 @@ "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true, + "paths": { + "@shared/*": [ + "src/app/shared/*" + ] + }, "target": "es2015", "module": "es2020", "lib": [ From 0635d85359aaf62e65546badf065fb45bd3fe8d6 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 24 Feb 2023 14:04:57 -0600 Subject: [PATCH 111/150] Add request to ApiAdvancedFilteredSearch --- .../library/rich-skills-library.component.ts | 6 ++-- .../richskill/list/skills-list.component.ts | 12 ++++++++ .../service/rich-skill-search.service.ts | 1 - .../richskill/service/rich-skill.service.ts | 29 +++++++++++++++++-- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/ui/src/app/richskill/library/rich-skills-library.component.ts b/ui/src/app/richskill/library/rich-skills-library.component.ts index d5c1966ed..dae0a94c3 100644 --- a/ui/src/app/richskill/library/rich-skills-library.component.ts +++ b/ui/src/app/richskill/library/rich-skills-library.component.ts @@ -38,8 +38,10 @@ export class RichSkillsLibraryComponent extends SkillsListComponent implements O this.setResults(new PaginatedSkills([], 0)) return } - const apiSearch = new ApiSearch({filtered: {statuses: this.selectedFilters}}) - this.resultsLoaded = this.richSkillService.getSkills(this.size, this.from, apiSearch, this.columnSort) + const apiSearch = new ApiSearch({filtered: this.selectedKeywords}) + this.resultsLoaded = this.richSkillService.getSkillsFiltered( + this.size, this.from, apiSearch, this.selectedFilters, this.columnSort + ) this.resultsLoaded.subscribe((results) => { this.setResults(results) }) diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index 4d156af92..d65ec3942 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -440,7 +440,19 @@ export class SkillsListComponent extends QuickLinksHelper { keywordsChange(keywords: FilterDropdown): void { this.keywords = keywords + console.log(this.keywords) this.loadNextPage() } + get selectedKeywords(): any { + const a: any = {} + const b: any = this.keywords + for (const key in this.keywords) { + if (b[key].length > 0) { + a[key] = b[key] + } + } + return a + } + } diff --git a/ui/src/app/richskill/service/rich-skill-search.service.ts b/ui/src/app/richskill/service/rich-skill-search.service.ts index 94ec4e756..8f5637627 100644 --- a/ui/src/app/richskill/service/rich-skill-search.service.ts +++ b/ui/src/app/richskill/service/rich-skill-search.service.ts @@ -38,7 +38,6 @@ export interface ApiAdvancedFilteredSearch { jobcodes?: string[] categories?: string[] employers?: string[] - statuses?: Set skillStatement?: string keywords?: string[] alignments?: string[] diff --git a/ui/src/app/richskill/service/rich-skill.service.ts b/ui/src/app/richskill/service/rich-skill.service.ts index 5e812f3d2..e116db334 100644 --- a/ui/src/app/richskill/service/rich-skill.service.ts +++ b/ui/src/app/richskill/service/rich-skill.service.ts @@ -1,5 +1,5 @@ import {Injectable} from "@angular/core" -import {HttpClient, HttpHeaders, HttpResponse} from "@angular/common/http" +import {HttpClient, HttpHeaders, HttpParams, HttpResponse} from "@angular/common/http" import {Observable, of, throwError} from "rxjs" import {ApiAuditLog, ApiSkill, ApiSortOrder, IAuditLog, ISkill} from "../ApiSkill" import {delay, map, retryWhen, share, switchMap} from "rxjs/operators" @@ -29,11 +29,11 @@ export class RichSkillService extends AbstractService { getSkills( size: number = 50, from: number = 0, - apiSearch: ApiSearch, + filterByStatuses: Set | undefined, sort: ApiSortOrder | undefined, ): Observable { - const params = this.buildTableParams(size, from, apiSearch.filtered?.statuses, sort) + const params = this.buildTableParams(size, from, filterByStatuses, sort) return this.get({ path: `${this.serviceUrl}`, params, @@ -47,6 +47,29 @@ export class RichSkillService extends AbstractService { })) } + getSkillsFiltered( + size: number = 50, + from: number = 0, + apiSearch: ApiSearch, + filterByStatuses: Set | undefined, + sort: ApiSortOrder | undefined, + ): Observable { + + const params = this.buildTableParams(size, from, filterByStatuses, sort) + return this.post({ + path: `${this.serviceUrl}/filter`, + params, + body: apiSearch + }) + .pipe(share()) + .pipe(map(({body, headers}) => { + return new PaginatedSkills( + body?.map(skill => skill) || [], + Number(headers.get("X-Total-Count")) + ) + })) + } + getSkillByUUID(uuid: string): Observable { const errorMsg = `Could not find skill by uuid [${uuid}]` return this.get({ From 0334b3669edfbd8a0b024d3699787faecd647994 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 24 Feb 2023 14:21:30 -0600 Subject: [PATCH 112/150] Update tests - Update test for getSkillsFiltered instead of getSkills. - Remove getSkillsMethod. --- .../service/rich-skill.service.spec.ts | 8 +++---- .../richskill/service/rich-skill.service.ts | 21 ------------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/ui/src/app/richskill/service/rich-skill.service.spec.ts b/ui/src/app/richskill/service/rich-skill.service.spec.ts index 575bd1e98..f3d1e7f73 100644 --- a/ui/src/app/richskill/service/rich-skill.service.spec.ts +++ b/ui/src/app/richskill/service/rich-skill.service.spec.ts @@ -76,17 +76,17 @@ describe("RichSkillService", () => { expect(testService).toBeTruthy() }) - it("getSkills should return", () => { + it("getSkills filter should return", () => { // Arrange RouterData.commands = [] AuthServiceData.isDown = false - const path = "api/skills?sort=name.asc&status=draft&size=3&from=0" + const path = "api/skills/filter?sort=name.asc&status=draft&size=3&from=0" const testData: PaginatedSkills = createMockPaginatedSkills(3, 10) const statuses = new Set([ PublishStatus.Draft ]) // Act // noinspection LocalVariableNamingConventionJS - const result$ = testService.getSkills(testData.skills.length, 0, statuses, ApiSortOrder.NameAsc) + const result$ = testService.getSkillsFiltered(testData.skills.length, 0, new ApiSearch({filtered: {}}), statuses, ApiSortOrder.NameAsc) // Assert result$ @@ -97,7 +97,7 @@ describe("RichSkillService", () => { }) const req = httpTestingController.expectOne(AppConfig.settings.baseApiUrl + "/" + path) - expect(req.request.method).toEqual("GET") + expect(req.request.method).toEqual("POST") req.flush(testData.skills, { headers: { "x-total-count": "" + testData.totalCount} }) diff --git a/ui/src/app/richskill/service/rich-skill.service.ts b/ui/src/app/richskill/service/rich-skill.service.ts index e116db334..33c378e16 100644 --- a/ui/src/app/richskill/service/rich-skill.service.ts +++ b/ui/src/app/richskill/service/rich-skill.service.ts @@ -26,27 +26,6 @@ export class RichSkillService extends AbstractService { private serviceUrl = "api/skills" - getSkills( - size: number = 50, - from: number = 0, - filterByStatuses: Set | undefined, - sort: ApiSortOrder | undefined, - ): Observable { - - const params = this.buildTableParams(size, from, filterByStatuses, sort) - return this.get({ - path: `${this.serviceUrl}`, - params, - }) - .pipe(share()) - .pipe(map(({body, headers}) => { - return new PaginatedSkills( - body?.map(skill => skill) || [], - Number(headers.get("X-Total-Count")) - ) - })) - } - getSkillsFiltered( size: number = 50, from: number = 0, From f3b5aa7704a4eba7192a1a36148f63443ec9bbe6 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 24 Feb 2023 16:01:10 -0600 Subject: [PATCH 113/150] Working on open api --- docs/int/osmt-v2.x-openapi3.yaml | 95 ++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/docs/int/osmt-v2.x-openapi3.yaml b/docs/int/osmt-v2.x-openapi3.yaml index fae964129..a8ebc464b 100644 --- a/docs/int/osmt-v2.x-openapi3.yaml +++ b/docs/int/osmt-v2.x-openapi3.yaml @@ -139,6 +139,59 @@ paths: items: type: boolean + /api/skills/filter: + post: + tags: + - Skills + summary: ApiAdvancedFilteredSearch + description: Search + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Search' + parameters: + - in: query + name: size + description: number of skills to return per page + schema: + type: number + default: 50 + - in: query + name: from + description: zero-indexed offset from beginning of records + schema: + type: number + default: 0 + - in: query + name: status + schema: + default: + - Unpublished + - Published + type: array + items: + $ref: '#/components/schemas/PublishStatus' + - in: query + name: sort + schema: + $ref: '#/components/schemas/SortOrder' + responses: + '202': + description: Accepted + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/SkillDoc' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResult' /api/skills: get: @@ -1334,6 +1387,8 @@ components: type: string advanced: $ref: '#/components/schemas/AdvancedSearch' + filtered: + $ref: '#/components/schemas/ApiAdvancedFilteredSearch' uuids: type: array items: @@ -1394,6 +1449,46 @@ components: - skill.asc - skill.desc + ApiAdvancedFilteredSearch: + type: object + properties: + categories: + type: array + items: + type: string + keywords: + type: array + items: + type: string + standars: + type: array + items: + type: string + certifications: + type: array + items: + type: string + alignments: + type: array + items: + type: string + jobcodes: + type: array + items: + type: string + employers: + type: array + items: + type: string + authors: + type: array + items: + type: string + occupations: + type: array + items: + type: string + TaskResult: type: object properties: From 2a994a1c803b5dd6b3fc5955f3de860bb2c2941c Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Fri, 24 Feb 2023 17:33:04 -0600 Subject: [PATCH 114/150] ApiJobCode or ApiNamedReference instead of string. --- ui/src/app/models/filter-dropdown.model.ts | 19 ++++++++------ .../richskill/list/skills-list.component.ts | 3 +-- .../filter-chips/filter-chips.component.html | 2 +- .../filter-chips/filter-chips.component.ts | 9 ++++--- .../filter-search.component.spec.ts | 25 +++++++++++++++++++ .../filter-search/filter-search.component.ts | 20 +++++++++++++++ .../search-multi-select.component.html | 4 +-- .../search-multi-select.component.ts | 21 +++++++++------- 8 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 ui/src/app/shared/filter-search/filter-search.component.spec.ts create mode 100644 ui/src/app/shared/filter-search/filter-search.component.ts diff --git a/ui/src/app/models/filter-dropdown.model.ts b/ui/src/app/models/filter-dropdown.model.ts index a0b9dbc05..57b1f6353 100644 --- a/ui/src/app/models/filter-dropdown.model.ts +++ b/ui/src/app/models/filter-dropdown.model.ts @@ -1,10 +1,13 @@ +import {ApiNamedReference} from "../richskill/ApiSkill" +import {ApiJobCode} from "../job-codes/Jobcode" + export interface FilterDropdown { - categories: string[] - keywords: string[] - standards: string[] - alignments: string[] - certifications: string[] - occupations: string[] - employers: string[] - authors: string[] + categories: ApiNamedReference[] + keywords: ApiNamedReference[] + standards: ApiNamedReference[] + alignments: ApiNamedReference[] + certifications: ApiNamedReference[] + occupations: ApiJobCode[] + employers: ApiNamedReference[] + authors: ApiNamedReference[] } diff --git a/ui/src/app/richskill/list/skills-list.component.ts b/ui/src/app/richskill/list/skills-list.component.ts index d65ec3942..80bf260f5 100644 --- a/ui/src/app/richskill/list/skills-list.component.ts +++ b/ui/src/app/richskill/list/skills-list.component.ts @@ -440,7 +440,6 @@ export class SkillsListComponent extends QuickLinksHelper { keywordsChange(keywords: FilterDropdown): void { this.keywords = keywords - console.log(this.keywords) this.loadNextPage() } @@ -449,7 +448,7 @@ export class SkillsListComponent extends QuickLinksHelper { const b: any = this.keywords for (const key in this.keywords) { if (b[key].length > 0) { - a[key] = b[key] + a[key] = b[key].map((i: any) => i.name ?? i.code) } } return a diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.html b/ui/src/app/shared/filter-chips/filter-chips.component.html index 887f0e9af..32829ec5e 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.html +++ b/ui/src/app/shared/filter-chips/filter-chips.component.html @@ -1,7 +1,7 @@
    {{name | titlecase}}
    - {{keyword}} + {{resultName(keyword)}} ×
    diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.ts b/ui/src/app/shared/filter-chips/filter-chips.component.ts index b62eba692..86f8a4427 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.ts +++ b/ui/src/app/shared/filter-chips/filter-chips.component.ts @@ -1,12 +1,15 @@ import {Component, EventEmitter, Input, Output} from "@angular/core" import {FormControl} from "@angular/forms" +import {ApiJobCode} from "../../job-codes/Jobcode" +import {ApiNamedReference} from "../../richskill/ApiSkill" +import {FilterSearchComponent} from "@shared/filter-search/filter-search.component" @Component({ selector: "app-filter-chips", templateUrl: "./filter-chips.component.html", styleUrls: ["./filter-chips.component.scss"] }) -export class FilterChipsComponent { +export class FilterChipsComponent extends FilterSearchComponent { @Input() name?: string @@ -15,9 +18,9 @@ export class FilterChipsComponent { @Output() remove: EventEmitter = new EventEmitter() - onRemoveChip(chipText: string): void { + onRemoveChip(chip: ApiJobCode | ApiNamedReference): void { const values = this.control?.value - const index = this.control?.value?.findIndex((i: string) => i === chipText) ?? 0 + const index = this.control?.value?.findIndex((i: ApiJobCode | ApiNamedReference) => this.areResultsEqual(chip, i)) ?? 0 if (index >= 0) { values.splice(index, 1) this.control?.patchValue(values) diff --git a/ui/src/app/shared/filter-search/filter-search.component.spec.ts b/ui/src/app/shared/filter-search/filter-search.component.spec.ts new file mode 100644 index 000000000..39ab187b4 --- /dev/null +++ b/ui/src/app/shared/filter-search/filter-search.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing" + +import { FilterSearchComponent } from "./filter-search.component" + +describe("FilterSearchComponent", () => { + let component: FilterSearchComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FilterSearchComponent ] + }) + .compileComponents() + }) + + beforeEach(() => { + fixture = TestBed.createComponent(FilterSearchComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it("should create", () => { + expect(component).toBeTruthy() + }) +}) diff --git a/ui/src/app/shared/filter-search/filter-search.component.ts b/ui/src/app/shared/filter-search/filter-search.component.ts new file mode 100644 index 000000000..21a856c04 --- /dev/null +++ b/ui/src/app/shared/filter-search/filter-search.component.ts @@ -0,0 +1,20 @@ +import {ApiJobCode} from "../../job-codes/Jobcode" +import {ApiNamedReference} from "../../richskill/ApiSkill" + + +export class FilterSearchComponent { + + areResultsEqual(i: ApiJobCode | ApiNamedReference, result: ApiJobCode | ApiNamedReference): boolean { + if (i instanceof ApiNamedReference && result instanceof ApiNamedReference) { + return i.name === result.name + } else if (i instanceof ApiJobCode && result instanceof ApiJobCode) { + return i.code === result.code + } + return false + } + + resultName(result: any): string { + return result.name ?? result.targetNodeName + " " + result.code + } + +} diff --git a/ui/src/app/shared/search-multi-select/search-multi-select.component.html b/ui/src/app/shared/search-multi-select/search-multi-select.component.html index dbeeca421..ec296544f 100644 --- a/ui/src/app/shared/search-multi-select/search-multi-select.component.html +++ b/ui/src/app/shared/search-multi-select/search-multi-select.component.html @@ -62,7 +62,7 @@
    Showing search results:
    - {{result}} + {{resultName(result)}}
    @@ -81,7 +81,7 @@
    - {{result}} + {{resultName(result)}}
    -
    +
    -
    +
    Date: Mon, 27 Feb 2023 12:14:16 -0600 Subject: [PATCH 119/150] Adding unit tests for standards, certifications, alignments and employers, refactoring Terms query build. --- .../edu/wgu/osmt/richskill/RichSkillEsRepo.kt | 49 ++--- .../wgu/osmt/richskill/RichSkillEsRepoTest.kt | 183 +++++++++++++++++- 2 files changed, 194 insertions(+), 38 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt index dd4e040e5..7cf40f895 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepo.kt @@ -71,21 +71,21 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear ) } - fun buildNestedQueries(path: String?=null, queryParams: List) : BoolQueryBuilder { + private fun buildNestedQueries(path: String?=null, queryParams: List) : BoolQueryBuilder { val disjunctionQuery = disMaxQuery() val queries = ArrayList() queryParams.let { it.map { param -> queries.add( - prefixQuery(path + ".keyword", param) + prefixQuery("$path.keyword", param) ) } } disjunctionQuery.innerQueries().addAll(queries) - return boolQuery().must(existsQuery(path + ".keyword")).must(disjunctionQuery) + return boolQuery().must(existsQuery("$path.keyword")).must(disjunctionQuery) } @@ -195,59 +195,34 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear } override fun generateBoolQueriesFromApiSearchWithFilters(bq: BoolQueryBuilder, filteredQuery: ApiFilteredSearch) { - - with(filteredQuery) { - categories?. let { bq.must(buildNestedQueries(RichSkillDoc::category.name, it)) } keywords?. let { it.mapNotNull { - bq.must( - TermsSetQueryBuilder( - "${RichSkillDoc::searchingKeywords.name}.keyword", keywords.toList() - ) - .setMinimumShouldMatchScript(Script(keywords.size.toString())) - ) - + bq.must(generateTermsSetQueryBuilder(RichSkillDoc::searchingKeywords.name, keywords)) } } standards?. let { it.mapNotNull { - bq.must( - TermsSetQueryBuilder( - "${RichSkillDoc::standards.name}.keyword", standards.toList() - ) - .setMinimumShouldMatchScript(Script(standards.size.toString())) - ) - + bq.must(generateTermsSetQueryBuilder(RichSkillDoc::standards.name, standards)) } } certifications?. let { it.mapNotNull { - bq.must( - TermsSetQueryBuilder( - "${RichSkillDoc::certifications.name}.keyword", certifications.toList() - ) - .setMinimumShouldMatchScript(Script(certifications.size.toString())) - ) - + bq.must(generateTermsSetQueryBuilder(RichSkillDoc::certifications.name, certifications)) } } alignments?. let { it.mapNotNull { - bq.must( - TermsSetQueryBuilder( - "${RichSkillDoc::alignments.name}.keyword", alignments.toList() - ) - .setMinimumShouldMatchScript(Script(alignments.size.toString())) - ) - + bq.must(generateTermsSetQueryBuilder(RichSkillDoc::alignments.name, alignments)) } } employers?. let { - bq.must(buildNestedQueries(RichSkillDoc::employers.name, it)) + it.mapNotNull { + bq.must(generateTermsSetQueryBuilder(RichSkillDoc::employers.name, employers)) + } } authors?. let { bq.must(buildNestedQueries(RichSkillDoc::author.name, it)) @@ -262,6 +237,10 @@ class CustomRichSkillQueriesImpl @Autowired constructor(override val elasticSear } } + private fun generateTermsSetQueryBuilder(fieldName: String, list: List): TermsSetQueryBuilder { + return TermsSetQueryBuilder("$fieldName.keyword", list).setMinimumShouldMatchScript(Script(list.size.toString())) + } + override fun richSkillPropertiesMultiMatch(query: String): BoolQueryBuilder { val isComplex = query.contains("\"") diff --git a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt index 47b290362..2da98d623 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt @@ -604,7 +604,6 @@ class RichSkillEsRepoTest @Autowired constructor( assertThat(alignmentsResult.searchHits.first().content.uuid).isEqualTo(skillByAlignments.uuid) } - @Test fun `search with categories filter should apply to filtered search`() { // Arrange @@ -627,9 +626,8 @@ class RichSkillEsRepoTest @Autowired constructor( assertThat(filteredSearchResult.searchHits.first().content.uuid).isEqualTo(skillWithCategory1.uuid) assertThat(filteredSearchResult.searchHits[1].content.uuid).isEqualTo(skillWithCategory3.uuid) } - @Test - fun `search with keywords filter should apply to filtered search with AND operaton between keywords`() { + fun `search with keywords filter should apply to filtered search with AND operator between keywords`() { // Arrange val skillWithKeywords1and2 = TestObjectHelpers.randomRichSkillDoc().copy(searchingKeywords = listOf("keyword1", "keyword2")) val skillWithKeywords2and3 = TestObjectHelpers.randomRichSkillDoc().copy(searchingKeywords = listOf("keyword2", "keyword3")) @@ -673,7 +671,186 @@ class RichSkillEsRepoTest @Autowired constructor( assertThat(filteredSearchResult3.searchHits.first().content.uuid).isEqualTo(skillWithKeywords3and4.uuid) assertThat(filteredSearchResult4).isEmpty() } + @Test + fun `search with standards filter should apply to filtered search with AND operator between standards`() { + // Arrange + val skillWithStandards1and2 = TestObjectHelpers.randomRichSkillDoc().copy(standards = listOf("standard1", "standard2")) + val skillWithStandards2and3 = TestObjectHelpers.randomRichSkillDoc().copy(standards = listOf("standard2", "standard3")) + val skillWithStandards3and4 = TestObjectHelpers.randomRichSkillDoc().copy(standards = listOf("standard3", "standard4")) + + richSkillEsRepo.saveAll(listOf(skillWithStandards1and2,skillWithStandards2and3,skillWithStandards3and4)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + standards = listOf("standard1", "standard2") + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + standards = listOf("standard2", "standard3") + ) + ) + ) + val filteredSearchResult3 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + standards = listOf("standard3", "standard4") + ) + ) + ) + val filteredSearchResult4 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + standards = listOf("standard1", "standard3") + ) + ) + ) + // Assert + assertThat(filteredSearchResult1.searchHits.first().content.uuid).isEqualTo(skillWithStandards1and2.uuid) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithStandards2and3.uuid) + assertThat(filteredSearchResult3.searchHits.first().content.uuid).isEqualTo(skillWithStandards3and4.uuid) + assertThat(filteredSearchResult4).isEmpty() + } + @Test + fun `Search with certifications filter should apply to filtered search with AND operator between certifications`() { + // Arrange + val skillWithCertifications1and2 = TestObjectHelpers.randomRichSkillDoc().copy(certifications = listOf("certification1", "certification2")) + val skillWithCertifications2and3 = TestObjectHelpers.randomRichSkillDoc().copy(certifications = listOf("certification2", "certification3")) + val skillWithCertifications3and4 = TestObjectHelpers.randomRichSkillDoc().copy(certifications = listOf("certification3", "certification4")) + + richSkillEsRepo.saveAll(listOf(skillWithCertifications1and2,skillWithCertifications2and3,skillWithCertifications3and4)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + certifications = listOf("certification1", "certification2") + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + certifications = listOf("certification2", "certification3") + ) + ) + ) + val filteredSearchResult3 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + certifications = listOf("certification3", "certification4") + ) + ) + ) + val filteredSearchResult4 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + certifications = listOf("certification1", "certification3") + ) + ) + ) + + // Assert + assertThat(filteredSearchResult1.searchHits.first().content.uuid).isEqualTo(skillWithCertifications1and2.uuid) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithCertifications2and3.uuid) + assertThat(filteredSearchResult3.searchHits.first().content.uuid).isEqualTo(skillWithCertifications3and4.uuid) + assertThat(filteredSearchResult4).isEmpty() + } + @Test + fun `Search with alignments filter should apply to filtered search with AND operator between alignments`() { + // Arrange + val skillWithAlignments1and2 = TestObjectHelpers.randomRichSkillDoc().copy(alignments = listOf("alignment1", "alignment2")) + val skillWithAlignments2and3 = TestObjectHelpers.randomRichSkillDoc().copy(alignments = listOf("alignment2", "alignment3")) + val skillWithAlignments3and4 = TestObjectHelpers.randomRichSkillDoc().copy(alignments = listOf("alignment3", "alignment4")) + + richSkillEsRepo.saveAll(listOf(skillWithAlignments1and2,skillWithAlignments2and3,skillWithAlignments3and4)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + alignments = listOf("alignment1", "alignment2") + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + alignments = listOf("alignment2", "alignment3") + ) + ) + ) + val filteredSearchResult3 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + alignments = listOf("alignment3", "alignment4") + ) + ) + ) + val filteredSearchResult4 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + alignments = listOf("alignment1", "alignment3") + ) + ) + ) + + // Assert + assertThat(filteredSearchResult1.searchHits.first().content.uuid).isEqualTo(skillWithAlignments1and2.uuid) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithAlignments2and3.uuid) + assertThat(filteredSearchResult3.searchHits.first().content.uuid).isEqualTo(skillWithAlignments3and4.uuid) + assertThat(filteredSearchResult4).isEmpty() + } + @Test + fun `Search with employers filter should apply to filtered search with AND operator between employers`() { + // Arrange + val skillWithEmployers1and2 = TestObjectHelpers.randomRichSkillDoc().copy(employers = listOf("employer1", "employer2")) + val skillWithEmployers2and3 = TestObjectHelpers.randomRichSkillDoc().copy(employers = listOf("employer2", "employer3")) + val skillWithEmployers3and4 = TestObjectHelpers.randomRichSkillDoc().copy(employers = listOf("employer3", "employer4")) + + richSkillEsRepo.saveAll(listOf(skillWithEmployers1and2,skillWithEmployers2and3,skillWithEmployers3and4)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + employers = listOf("employer1", "employer2") + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + employers = listOf("employer2", "employer3") + ) + ) + ) + val filteredSearchResult3 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + employers = listOf("employer3", "employer4") + ) + ) + ) + val filteredSearchResult4 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + employers = listOf("employer1", "employer3") + ) + ) + ) + + // Assert + assertThat(filteredSearchResult1.searchHits.first().content.uuid).isEqualTo(skillWithEmployers1and2.uuid) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithEmployers2and3.uuid) + assertThat(filteredSearchResult3.searchHits.first().content.uuid).isEqualTo(skillWithEmployers3and4.uuid) + assertThat(filteredSearchResult4).isEmpty() + } @Test fun testFindSimilar() { // Arrange From 52c3875e72d33f33cc3910b4a9af186f2f5bb0f2 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Mon, 27 Feb 2023 12:03:57 -0600 Subject: [PATCH 120/150] Update open api doc - Add headers to /skills/filter. --- docs/int/osmt-v2.x-openapi3.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/int/osmt-v2.x-openapi3.yaml b/docs/int/osmt-v2.x-openapi3.yaml index a8ebc464b..174c07ad4 100644 --- a/docs/int/osmt-v2.x-openapi3.yaml +++ b/docs/int/osmt-v2.x-openapi3.yaml @@ -143,8 +143,8 @@ paths: post: tags: - Skills - summary: ApiAdvancedFilteredSearch - description: Search + summary: Advanced filtered search for skills + description: Return list of skills that match the provided query requestBody: required: true content: @@ -179,7 +179,12 @@ paths: $ref: '#/components/schemas/SortOrder' responses: '202': - description: Accepted + description: Ok + headers: + Link: + $ref: '#/components/headers/Link' + X-Total-Count: + $ref: '#/components/headers/XTotalCount' content: application/json: schema: From af9acc6b0c13027a6b326c84dcd4e7eb98a2f9cf Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Mon, 27 Feb 2023 14:33:45 -0600 Subject: [PATCH 121/150] Adding unit tests for occupations filter only --- .../wgu/osmt/richskill/RichSkillEsRepoTest.kt | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt index 2da98d623..91be0dd09 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt @@ -852,6 +852,102 @@ class RichSkillEsRepoTest @Autowired constructor( assertThat(filteredSearchResult4).isEmpty() } @Test + fun `search with occupations filter should apply to filtered search`() { + // Arrange + val jobCodes1and2 = listOf( + TestObjectHelpers.randomJobCode().copy(code = "10-1111.11", id = TestObjectHelpers.elasticIdCounter), + TestObjectHelpers.randomJobCode().copy(code = "10-2222.22", id = TestObjectHelpers.elasticIdCounter), + ) + val jobCodes2and3 = listOf( + TestObjectHelpers.randomJobCode().copy(code = "10-2222.22", id = TestObjectHelpers.elasticIdCounter), + TestObjectHelpers.randomJobCode().copy(code = "10-3333.33", id = TestObjectHelpers.elasticIdCounter), + ) + val jobCodes3and4 = listOf( + TestObjectHelpers.randomJobCode().copy(code = "10-3333.33", id = TestObjectHelpers.elasticIdCounter), + TestObjectHelpers.randomJobCode().copy(code = "10-4444.44", id = TestObjectHelpers.elasticIdCounter), + ) + + val skillWithOccupations1and2 = TestObjectHelpers.randomRichSkillDoc() + .copy(jobCodes = jobCodes1and2) + val skillWithOccupations2and3 = TestObjectHelpers.randomRichSkillDoc() + .copy(jobCodes = jobCodes2and3) + val skillWithOccupations3and4 = TestObjectHelpers.randomRichSkillDoc() + .copy(jobCodes = jobCodes3and4) + + richSkillEsRepo.saveAll(listOf(skillWithOccupations1and2, skillWithOccupations2and3, skillWithOccupations3and4)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + advanced = ApiAdvancedSearch( + occupations = listOf( + "10-11", + "10-22" + ) + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + advanced = ApiAdvancedSearch( + occupations = listOf( + "10-22", + "10-33" + ) + ) + ) + ) + val filteredSearchResult3 = richSkillEsRepo.byApiSearch( + ApiSearch( + advanced = ApiAdvancedSearch( + occupations = listOf( + "10-33", + "10-44" + ) + ) + ) + ) + val filteredSearchResult4 = richSkillEsRepo.byApiSearch( + ApiSearch( + advanced = ApiAdvancedSearch( + occupations = listOf( + "10-11", + "10-33" + ) + ) + ) + ) + + // Assert + assertThat(filteredSearchResult1.searchHits.first().content.uuid).isEqualTo(skillWithOccupations1and2.uuid) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithOccupations2and3.uuid) + assertThat(filteredSearchResult3.searchHits.first().content.uuid).isEqualTo(skillWithOccupations3and4.uuid) + assertThat(filteredSearchResult4).isEmpty() + + } + @Test + fun `search with authors filter should apply to filtered search`() { + // Arrange + val skillWithAuthor1 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author1") + val skillWithAuthor2 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author2") + val skillWithAuthor3 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author3") + + richSkillEsRepo.saveAll(listOf(skillWithAuthor1,skillWithAuthor2,skillWithAuthor3)) + + // Act + val filteredSearchResult = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + authors = listOf("author1", "author3") + ) + ) + ) + + // Assert + assertThat(filteredSearchResult.searchHits.first().content.uuid).isEqualTo(skillWithAuthor1.uuid) + assertThat(filteredSearchResult.searchHits[1].content.uuid).isEqualTo(skillWithAuthor3.uuid) + } + @Test fun testFindSimilar() { // Arrange val numOfSkills = 2L From c84c96bf32b4bb4731f9f1d10927f82d7edaf5eb Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Tue, 28 Feb 2023 10:33:25 -0600 Subject: [PATCH 122/150] Adding unit tests for mixed filters applied --- .../wgu/osmt/richskill/RichSkillEsRepoTest.kt | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt index 91be0dd09..83285578d 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt @@ -947,6 +947,87 @@ class RichSkillEsRepoTest @Autowired constructor( assertThat(filteredSearchResult.searchHits.first().content.uuid).isEqualTo(skillWithAuthor1.uuid) assertThat(filteredSearchResult.searchHits[1].content.uuid).isEqualTo(skillWithAuthor3.uuid) } + @Test + fun `search with authors & categories filter should apply to filtered search with AND operator between fields, and OR operator between values`() { + // Arrange + val skillWithAuthor1AndCategory1 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author1", category = "category1") + val skillWithAuthor2AndCategory2 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author2", category = "category2") + val skillWithAuthor1AndCategory3 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author1", category = "category3") + val skillWithAuthor2AndCategory3 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author2", category = "category3") + val skillWithAuthor3AndCategory3 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author3", category = "category3") + + richSkillEsRepo.saveAll(listOf(skillWithAuthor1AndCategory1,skillWithAuthor2AndCategory2,skillWithAuthor3AndCategory3, + skillWithAuthor1AndCategory3,skillWithAuthor2AndCategory3)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + authors = listOf("author1", "author2"), + categories = listOf("category1", "category2") + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + authors = listOf("author1", "author2", "author3"), + categories = listOf("category1", "category2", "category3") + ) + ) + ) + + // Assert + assertThat(filteredSearchResult1.searchHits).hasSize(2) + assertThat(filteredSearchResult1.searchHits.first().content.uuid).isEqualTo(skillWithAuthor1AndCategory1.uuid) + assertThat(filteredSearchResult1.searchHits[1].content.uuid).isEqualTo(skillWithAuthor2AndCategory2.uuid) + assertThat(filteredSearchResult2.searchHits).hasSize(5) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithAuthor1AndCategory1.uuid) + assertThat(filteredSearchResult2.searchHits[4].content.uuid).isEqualTo(skillWithAuthor2AndCategory3.uuid) + } + @Test + fun `search with authors & categories & keywords filter should apply to filtered search with AND operator between fields, and OR operator between categories and authors and AND between keywords`() { + // Arrange + val skillWithAuthor1AndCategory1 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author1", category = "category1", + searchingKeywords = listOf("keyword1")) + val skillWithAuthor2AndCategory2 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author2", category = "category2", + searchingKeywords = listOf("keyword2")) + val skillWithAuthor1AndCategory3 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author1", category = "category3", + searchingKeywords = listOf("keyword1", "keyword3")) + val skillWithAuthor2AndCategory3 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author2", category = "category3", + searchingKeywords = listOf("keyword2", "keyword3")) + val skillWithAuthor3AndCategory3 = TestObjectHelpers.randomRichSkillDoc().copy(author = "author3", category = "category3", + searchingKeywords = listOf("keyword1", "keyword2", "keyword3")) + + richSkillEsRepo.saveAll(listOf(skillWithAuthor1AndCategory1,skillWithAuthor2AndCategory2,skillWithAuthor3AndCategory3, + skillWithAuthor1AndCategory3,skillWithAuthor2AndCategory3)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + authors = listOf("author1", "author2"), + categories = listOf("category1", "category2"), + keywords = listOf("keyword1", "keyword2") + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + authors = listOf("author1", "author2", "author3"), + categories = listOf("category1", "category2", "category3"), + keywords = listOf("keyword1", "keyword2", "keyword3") + ) + ) + ) + + // Assert + assertThat(filteredSearchResult1.searchHits).isEmpty() + assertThat(filteredSearchResult2.searchHits).hasSize(1) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithAuthor3AndCategory3.uuid) + } + @Test fun testFindSimilar() { // Arrange From 97d97c9512bdc84d086e8cd54c801b5376bfc97e Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Tue, 28 Feb 2023 12:06:32 -0600 Subject: [PATCH 123/150] Adding unit tests for more mixed filters applied --- .../wgu/osmt/richskill/RichSkillController.kt | 3 +- .../wgu/osmt/richskill/RichSkillEsRepoTest.kt | 80 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt index e1b582e80..29510b3c6 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt @@ -2,6 +2,7 @@ package edu.wgu.osmt.richskill import edu.wgu.osmt.HasAllPaginated import edu.wgu.osmt.RoutePaths +import edu.wgu.osmt.RoutePaths.SKILLS_FILTER import edu.wgu.osmt.api.GeneralApiException import edu.wgu.osmt.api.model.ApiSearch import edu.wgu.osmt.api.model.ApiSkill @@ -108,7 +109,7 @@ class RichSkillController @Autowired constructor( responseHeaders.add("X-Total-Count", countAllFiltered.toString()) uriComponentsBuilder - .path(allPaginatedPath) + .path(SKILLS_FILTER) .queryParam(RoutePaths.QueryParams.FROM, from) .queryParam(RoutePaths.QueryParams.SIZE, size) .queryParam(RoutePaths.QueryParams.SORT, sort) diff --git a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt index 83285578d..c3fbdf885 100644 --- a/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt +++ b/api/src/test/kotlin/edu/wgu/osmt/richskill/RichSkillEsRepoTest.kt @@ -1027,6 +1027,86 @@ class RichSkillEsRepoTest @Autowired constructor( assertThat(filteredSearchResult2.searchHits).hasSize(1) assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skillWithAuthor3AndCategory3.uuid) } + @Test + fun `search with categories, keywords & standards filter should apply to filtered search with AND operator between fields, and OR operator between categories and AND operator between keywords and standards`() { + // Arrange + val skill1 = TestObjectHelpers.randomRichSkillDoc().copy(category = "category1", + searchingKeywords = listOf("keyword1"), + standards = listOf("standard1") + ) + val skill2 = TestObjectHelpers.randomRichSkillDoc().copy(category = "category2", + searchingKeywords = listOf("keyword1", "keyword2"), + standards = listOf("standard1", "standard2") + ) + val skill3 = TestObjectHelpers.randomRichSkillDoc().copy(category = "category3", + searchingKeywords = listOf("keyword1", "keyword2", "keyword3"), + standards = listOf("standard1", "standard2", "standard3") + ) + val skill4 = TestObjectHelpers.randomRichSkillDoc().copy(category = "category4", + searchingKeywords = listOf("keyword1", "keyword2", "keyword3", "keyword4"), + standards = listOf("standard1", "standard2", "standard3", "standard4") + ) + + + richSkillEsRepo.saveAll(listOf(skill1,skill2,skill3,skill4)) + + // Act + val filteredSearchResult1 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + categories = listOf("category1", "category2"), + keywords = listOf("keyword1", "keyword2"), + standards = listOf("standard1") + ) + ) + ) + val filteredSearchResult2 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + categories = listOf("category1", "category2", "category3"), + keywords = listOf("keyword1", "keyword2", "keyword3"), + standards = listOf("standard1", "standard2") + ) + ) + ) + val filteredSearchResult3 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + categories = listOf("category1", "category2", "category3"), + keywords = listOf("keyword1", "keyword2", "keyword3"), + standards = listOf("standard1", "standard2", "standard3") + ) + ) + ) + val filteredSearchResult4 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + categories = listOf("category1", "category2", "category3"), + keywords = listOf("keyword1", "keyword2", "keyword3"), + standards = listOf("standard1", "standard2", "standard3", "standard4") + ) + ) + ) + val filteredSearchResult5 = richSkillEsRepo.byApiSearch( + ApiSearch( + filtered = ApiFilteredSearch( + categories = listOf("category1", "category2", "category3", "category4"), + keywords = listOf("keyword1"), + standards = listOf("standard1") + ) + ) + ) + + // Assert + assertThat(filteredSearchResult1.searchHits).hasSize(1) + assertThat(filteredSearchResult1.searchHits.first().content.uuid).isEqualTo(skill2.uuid) + assertThat(filteredSearchResult2.searchHits).hasSize(1) + assertThat(filteredSearchResult2.searchHits.first().content.uuid).isEqualTo(skill3.uuid) + assertThat(filteredSearchResult3.searchHits).hasSize(1) + assertThat(filteredSearchResult3.searchHits.first().content.uuid).isEqualTo(skill3.uuid) + assertThat(filteredSearchResult4.searchHits).isEmpty() + assertThat(filteredSearchResult5.searchHits).hasSize(4) + } @Test fun testFindSimilar() { From 5690c51727400c21c71db6def3f81577ea504c90 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Tue, 28 Feb 2023 16:32:29 -0600 Subject: [PATCH 124/150] Removing replaced endpoint --- .../wgu/osmt/richskill/RichSkillController.kt | 18 +------- docs/int/osmt-v2.x-openapi3.yaml | 46 ------------------- 2 files changed, 1 insertion(+), 63 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt index 29510b3c6..127672816 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/richskill/RichSkillController.kt @@ -64,23 +64,7 @@ class RichSkillController @Autowired constructor( override val allPaginatedPath: String = RoutePaths.SKILLS_LIST override val sortOrderCompanion = SkillSortEnum.Companion - @GetMapping(RoutePaths.SKILLS_LIST, produces = [MediaType.APPLICATION_JSON_VALUE]) - @ResponseBody - override fun allPaginated( - uriComponentsBuilder: UriComponentsBuilder, - size: Int, - from: Int, - status: Array, - sort: String?, - @AuthenticationPrincipal user: Jwt? - ): HttpEntity> { - if (!appConfig.allowPublicLists && user === null) { - throw GeneralApiException("Unauthorized", HttpStatus.UNAUTHORIZED) - } - return super.allPaginated(uriComponentsBuilder, size, from, status, sort, user) - } - - @PostMapping(RoutePaths.SKILLS_FILTER, produces = [MediaType.APPLICATION_JSON_VALUE]) + @PostMapping(SKILLS_FILTER, produces = [MediaType.APPLICATION_JSON_VALUE]) @ResponseBody fun allPaginatedWithFilters( uriComponentsBuilder: UriComponentsBuilder, diff --git a/docs/int/osmt-v2.x-openapi3.yaml b/docs/int/osmt-v2.x-openapi3.yaml index 42f0467d8..8f96233ef 100644 --- a/docs/int/osmt-v2.x-openapi3.yaml +++ b/docs/int/osmt-v2.x-openapi3.yaml @@ -199,52 +199,6 @@ paths: $ref: '#/components/schemas/ErrorResult' /api/skills: - get: - summary: Get all skills - description: Returns paginated list of all skills in the library - parameters: - - in: query - name: size - description: number of skills to return per page - schema: - type: number - default: 50 - - in: query - name: from - description: zero-indexed offset from beginning of records - schema: - type: number - default: 0 - - in: query - name: status - schema: - default: - - Unpublished - - Published - type: array - items: - $ref: '#/components/schemas/PublishStatus' - - in: query - name: sort - schema: - $ref: '#/components/schemas/SortOrder' - responses: - '200': - description: OK - headers: - Link: - $ref: '#/components/headers/Link' - X-Total-Count: - $ref: '#/components/headers/XTotalCount' - - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/SkillDoc' - tags: - - Skills post: tags: - Skills From cc3d5ff6934de883ee0fb86f73d085deb4027e22 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Mar 2023 15:28:52 -0600 Subject: [PATCH 125/150] Adding logic to retrieve all keywords incidences of a particular type --- .../edu/wgu/osmt/keyword/KeywordEsRepo.kt | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/keyword/KeywordEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/keyword/KeywordEsRepo.kt index 48ac60879..efee9ff06 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/keyword/KeywordEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/keyword/KeywordEsRepo.kt @@ -25,26 +25,38 @@ interface CustomKeywordRepository { class CustomKeywordRepositoryImpl @Autowired constructor(override val elasticSearchTemplate: ElasticsearchRestTemplate) : CustomKeywordRepository { override fun typeAheadSearch(query: String, type: KeywordTypeEnum): SearchHits { - val limitedPageable = OffsetPageable(0, 10, null) + val limitedPageable: OffsetPageable val bq = QueryBuilders.boolQuery() + val nsq: NativeSearchQueryBuilder - val nsq: NativeSearchQueryBuilder = - NativeSearchQueryBuilder().withPageable(limitedPageable).withQuery(bq).withSort(SortBuilders.scoreSort()) + if(query.isEmpty()){ //retrieve all + limitedPageable = OffsetPageable(0, 10000, null) + nsq = NativeSearchQueryBuilder().withPageable(limitedPageable).withQuery(bq).withSort(SortBuilders.scoreSort()) + bq + .must(QueryBuilders.termQuery(Keyword::type.name, type.name)) + .should( + QueryBuilders.matchAllQuery() + ) - bq - .must(QueryBuilders.termQuery(Keyword::type.name, type.name)) - .should( - QueryBuilders.matchBoolPrefixQuery( - Keyword::value.name, - query + } + else { + limitedPageable = OffsetPageable(0, 10, null) + nsq = NativeSearchQueryBuilder().withPageable(limitedPageable).withQuery(bq).withSort(SortBuilders.scoreSort()) + bq + .must(QueryBuilders.termQuery(Keyword::type.name, type.name)) + .should( + QueryBuilders.matchBoolPrefixQuery( + Keyword::value.name, + query + ) ) - ) - .should( - QueryBuilders.matchPhraseQuery( - Keyword::value.name, - query - ).boost(5f) - ).minimumShouldMatch(1) + .should( + QueryBuilders.matchPhraseQuery( + Keyword::value.name, + query + ).boost(5f) + ).minimumShouldMatch(1) + } return elasticSearchTemplate.search(nsq.build(), Keyword::class.java) } From 6ab4ccba23fd4b8aac3de868e3b0225c055b4e31 Mon Sep 17 00:00:00 2001 From: Jose Chavez Date: Wed, 1 Mar 2023 15:51:48 -0600 Subject: [PATCH 126/150] Adding logic to retrieve all jobcodes incidences of a particular type --- .../kotlin/edu/wgu/osmt/jobcode/JobCodeEsRepo.kt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/api/src/main/kotlin/edu/wgu/osmt/jobcode/JobCodeEsRepo.kt b/api/src/main/kotlin/edu/wgu/osmt/jobcode/JobCodeEsRepo.kt index aab76bfa4..b917b9e24 100644 --- a/api/src/main/kotlin/edu/wgu/osmt/jobcode/JobCodeEsRepo.kt +++ b/api/src/main/kotlin/edu/wgu/osmt/jobcode/JobCodeEsRepo.kt @@ -28,13 +28,19 @@ class CustomJobCodeRepositoryImpl @Autowired constructor(override val elasticSea CustomJobCodeRepository { override fun typeAheadSearch(query: String): SearchHits { - val limitedPageable = OffsetPageable(0, 10, null) - val disjunctionQuery = JobCodeQueries.multiPropertySearch(query) + val limitedPageable: OffsetPageable + val nsq: NativeSearchQueryBuilder + + limitedPageable = if (query.isEmpty()) { + OffsetPageable(0, 10000, null) + } else { + OffsetPageable(0, 10, null) - val nsq: NativeSearchQueryBuilder = + } + val disjunctionQuery = JobCodeQueries.multiPropertySearch(query) + nsq = NativeSearchQueryBuilder().withPageable(limitedPageable).withQuery(disjunctionQuery) .withSort(SortBuilders.scoreSort()) - return elasticSearchTemplate.search(nsq.build(), JobCode::class.java) } } From 90ca03991eeec3469c1c14402cb3b17c20b45cc1 Mon Sep 17 00:00:00 2001 From: manuel-delvillar <68391066+manuel-delvillar@users.noreply.github.com> Date: Wed, 1 Mar 2023 14:28:33 -0600 Subject: [PATCH 127/150] Add close and decrease font size --- .../shared/filter-chips/filter-chips.component.scss | 4 ++++ .../filter-drop-down/filter-dropdown.component.html | 11 ++++++++++- .../filter-drop-down/filter-dropdown.component.scss | 9 ++++++++- .../filter-drop-down/filter-dropdown.component.ts | 9 ++++++++- .../search-multi-select.component.html | 2 +- .../search-multi-select.component.scss | 12 ++++++++++++ 6 files changed, 43 insertions(+), 4 deletions(-) diff --git a/ui/src/app/shared/filter-chips/filter-chips.component.scss b/ui/src/app/shared/filter-chips/filter-chips.component.scss index b9ebea67f..800d86352 100644 --- a/ui/src/app/shared/filter-chips/filter-chips.component.scss +++ b/ui/src/app/shared/filter-chips/filter-chips.component.scss @@ -1,3 +1,7 @@ +.header { + font-size: 14px; +} + .chip-wrapper { display: flex; flex-wrap: wrap; diff --git a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html index 665a9a454..ba72e1712 100644 --- a/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html +++ b/ui/src/app/shared/filter-drop-down/filter-dropdown.component.html @@ -1,11 +1,20 @@