feat: Initialize Strata KitchenSink application boilerplate

This sets up the foundational structure for a .NET Core 6 / React project,
demonstrating common architectural patterns, Docker integration, and key
Strata libraries for API, data access (EF Core), background jobs (Hangfire),
real-time communication (SignalR), and various frontend UI components.
This commit is contained in:
Thom Lamb
2026-06-23 10:58:15 -05:00
parent 1d2c6543dd
commit 0979371a57
125 changed files with 25811 additions and 218 deletions
@@ -0,0 +1,44 @@
export default class importExportPage {
getImportExportMenu() {
return cy.findByRole("menuitem", {name: 'Import Export'})
}
getPageHeading() {
return cy.findByRole("heading", {name: 'Import Export'})
}
verifyCardTitle(titleName: string) {
return cy.findAllByText(titleName).first()
}
clickExport(){
return cy.findByRole("button", {name: 'Export'}).click()
}
verifyExport(filePath: string, data: string[]){
// intercept the call to avoid using arbitrary wait for the download to complete
cy.intercept('GET', 'https://kitchensink-api.dev.stratanetwork.net/api/v1/departments/export').as('Export')
cy.wait(10000)
// call the parseXlsx task we created above to parse the excel and return data as json
cy.task('parseXlsx', {filePath})
.then(jsonData => {
//the assertion to check if that data matches the data we expected the excel file to have.
expect(jsonData[0].data[0]).to.eqls(data)
})
return
}
importFile(file: string) {
return cy.get("input[type=file]").attachFile("Departments_Export_" + new Date().toJSON().slice(0,10) + ".xlsx")
}
verifyImport(){
cy.intercept('POST', 'https://kitchensink-api.dev.stratanetwork.net/api/v1/departments/import').as ('Import')
cy.wait('@Import').then(() => {
cy.get(".ant-notification").should("contain", "departments updated.")
})
return
}
}
@@ -0,0 +1,22 @@
export function loginLocally() {
cy.login(
Cypress.env('username'),
Cypress.env('password'),
Cypress.env('dbguid'),
Cypress.env('clientId'));
}
export function loginInteractively() {
cy.visit('/');
enterText('Email or Username', Cypress.env('username'));
cy.findAllByRole('button', { name: 'Next' }).click();
enterText('Password', Cypress.env('password'));
enterText('Org PIN', Cypress.env('orgPin'));
cy.findAllByRole('button', { name: 'Next' }).click();
}
function enterText(name: string, value: string) {
cy.findByLabelText(name).type(value);
}
@@ -0,0 +1,144 @@
import { eq } from "cypress/types/lodash"
export default class scoreMemberTreePage {
getScoreMemberTreeMenu() {
return cy.findByRole("menuitem", {name: 'Score Member Tree'})
}
getPageHeading() {
return cy.findByRole("heading", {name: 'Score Member Tree'})
}
chooseTab(tabName: string) {
return cy.findByRole("tab", {name: tabName}).should("be.visible").click()
}
getSelectedTab(tabName: string) {
return cy.findByRole("tabpanel", {name: tabName})
}
selectHierarchy(hierarchyName: string) {
cy.findByRole("combobox").parent().next().click().should("be.visible")
return cy.findAllByTitle(hierarchyName).first().click()
}
expandNode(nodes: string[], level: 'single' | 'multi') {
let len = nodes.length
for(let i = 0; i < len; i++) {
if(level == 'single') {
cy.findByTitle(nodes[i]).prev().click()
} else if(level == 'multi') {
cy.findByTitle(nodes[i]).prev().prev().click()
}
}
return
}
selectNode(nodeName: string) {
return cy.findByTitle(nodeName).click()
}
verifySelectedMember(memberName: string) {
return cy.findByText("Selected: " + memberName)
}
checkNodes(nodeNames: string[]) {
let len = nodeNames.length
for(let i = 0; i < len; i++) {
cy.findByTitle(nodeNames[i]).click()
}
return
}
clickOpen(buttonName: string) {
return cy.findByRole("button", {name: buttonName}).click()
}
clickSave() {
return cy.findByRole("button", {name: "Save"}).click()
}
verifySavedMembers(memberNames: string[]) {
let len = memberNames.length
for(let i = 0; i < len; i++) {
cy.findByText(memberNames[i]).should("be.visible")
}
}
getSelectedHierarchy() {
return cy.findByRole("combobox").parent().next()
}
verifyCheckedNodes(nodeNames: string[]) {
let len = nodeNames.length
for(let i = 0; i < len; i++) {
cy.findByTitle(nodeNames[i]).prev().should("have.attr", "class").and("contain", 'checkbox-checked')
}
return
}
verifyUncheckedNodes(nodeNames: string[]) {
let len = nodeNames.length
for(let i = 0; i < len; i++) {
cy.findByTitle(nodeNames[i]).prev().should("have.attr", "class").and("not.contain", 'checkbox-checked')
}
return
}
verifyNodesVisible(nodeNames: string[]) {
let len = nodeNames.length
for(let i = 0; i < len; i++) {
cy.findByTitle(nodeNames[i]).should("be.visible")
}
}
verifyNodesDoNotExist(nodeNames: string[]) {
let len = nodeNames.length
for(let i = 0; i < len; i++) {
cy.findByTitle(nodeNames[i]).should("not.exist")
}
}
clickCancel() {
return cy.findByRole("button", {name: "Cancel"}).click()
}
selectName(selectedName: string) {
cy.findByRole("combobox").click().should("exist")
return cy.findAllByTitle(selectedName).first().click()
}
verifySelectedName(selectedName: string) {
return cy.findByText("Selected Name: " + selectedName)
}
verifySelectedVAlue(selectedValue: string) {
return cy.findByText("Selected Value: " + selectedValue)
}
getMemberList() {
cy.intercept('GET', 'https://schema-api.dev.stratanetwork.net/api/v2/dimensions/Department/hierarchies').as('Hierarchies')
cy.intercept('GET', 'https://schema-api.dev.stratanetwork.net/api/v2/dimensions/Department/members?columns=id&columns=name').as('MemberList')
cy.intercept('GET', 'https://schema-api.dev.stratanetwork.net/api/v2/dimensions/Department').as('DepartmentList')
return
}
getHierarchyNodeList() {
cy.intercept('POST', 'https://schema-api.dev.stratanetwork.net/api/v2/hierarchies/a28d670c-3c10-4be9-bc2d-1148f240c8ee/nodes?hierarchyPath=').as('DepartmentNodeList')
cy.intercept('POST', 'https://schema-api.dev.stratanetwork.net/api/v2/hierarchies/7c671eb2-c014-4daf-90d5-d87f891a6664/nodes?hierarchyPath=').as('CAPDepartmentNodeList')
return
}
clickAllView() {
return cy.findByText("All").click();
}
clickSelectedView() {
return cy.findByText("Selected").click();
}
}
@@ -0,0 +1,6 @@
export default class welcomePage {
getWelcomeMenu() {
return cy.findByRole("menuitem", {name: 'Welcome'})
}
}