diff --git a/.github/workflows/snjs.pr.yml b/.github/workflows/snjs.pr.yml index 124c3cf3b..172ff0fa1 100644 --- a/.github/workflows/snjs.pr.yml +++ b/.github/workflows/snjs.pr.yml @@ -26,6 +26,8 @@ jobs: uses: actions/checkout@v3 - name: Install dependencies run: yarn install --immutable + - name: Build + run: yarn build:snjs - name: Login to Docker Hub uses: docker/login-action@v2 with: diff --git a/packages/web/src/javascripts/Controllers/AccountMenu/StructuredItemsCount.ts b/packages/models/src/Domain/Abstract/Item/Types/ItemCounts.ts similarity index 65% rename from packages/web/src/javascripts/Controllers/AccountMenu/StructuredItemsCount.ts rename to packages/models/src/Domain/Abstract/Item/Types/ItemCounts.ts index 139cf2131..d3abc32ad 100644 --- a/packages/web/src/javascripts/Controllers/AccountMenu/StructuredItemsCount.ts +++ b/packages/models/src/Domain/Abstract/Item/Types/ItemCounts.ts @@ -1,4 +1,4 @@ -export type StructuredItemsCount = { +export type ItemCounts = { notes: number tags: number deleted: number diff --git a/packages/models/src/Domain/Abstract/Item/index.ts b/packages/models/src/Domain/Abstract/Item/index.ts index 68ceeacf8..23c09f03c 100644 --- a/packages/models/src/Domain/Abstract/Item/index.ts +++ b/packages/models/src/Domain/Abstract/Item/index.ts @@ -24,6 +24,7 @@ export * from './Mutator/TransactionalMutation' export * from './Types/AppDataField' export * from './Types/ConflictStrategy' export * from './Types/DefaultAppDomain' +export * from './Types/ItemCounts' export * from './Types/ItemStream' export * from './Types/MutationType' export * from './Types/SingletonStrategy' diff --git a/packages/services/src/Domain/Item/ItemCounter.spec.ts b/packages/services/src/Domain/Item/ItemCounter.spec.ts new file mode 100644 index 000000000..0b27d9ed9 --- /dev/null +++ b/packages/services/src/Domain/Item/ItemCounter.spec.ts @@ -0,0 +1,31 @@ +import { ContentType } from '@standardnotes/common' +import { SNNote, SNTag } from '@standardnotes/models' +import { ItemCounter } from './ItemCounter' + +describe('ItemCounter', () => { + const createCounter = () => new ItemCounter() + + it('should count distinct item counts', () => { + const items = [ + { + archived: true, + } as jest.Mocked, + { + trashed: true, + } as jest.Mocked, + { + content_type: ContentType.Note, + } as jest.Mocked, + { + content_type: ContentType.Tag, + } as jest.Mocked, + ] + + expect(createCounter().countNotesAndTags(items)).toEqual({ + archived: 1, + deleted: 1, + notes: 1, + tags: 1, + }) + }) +}) diff --git a/packages/services/src/Domain/Item/ItemCounter.ts b/packages/services/src/Domain/Item/ItemCounter.ts new file mode 100644 index 000000000..a609fe19f --- /dev/null +++ b/packages/services/src/Domain/Item/ItemCounter.ts @@ -0,0 +1,40 @@ +import { ContentType } from '@standardnotes/common' +import { SNNote, SNTag, ItemCounts } from '@standardnotes/models' + +import { ItemCounterInterface } from './ItemCounterInterface' + +export class ItemCounter implements ItemCounterInterface { + countNotesAndTags(items: Array): ItemCounts { + const counts: ItemCounts = { + notes: 0, + archived: 0, + deleted: 0, + tags: 0, + } + + for (const item of items) { + if (item.archived) { + counts.archived++ + + continue + } + if (item.trashed) { + counts.deleted++ + + continue + } + if (item.content_type === ContentType.Note) { + counts.notes++ + + continue + } + if (item.content_type === ContentType.Tag) { + counts.tags++ + + continue + } + } + + return counts + } +} diff --git a/packages/services/src/Domain/Item/ItemCounterInterface.ts b/packages/services/src/Domain/Item/ItemCounterInterface.ts new file mode 100644 index 000000000..4c5647d96 --- /dev/null +++ b/packages/services/src/Domain/Item/ItemCounterInterface.ts @@ -0,0 +1,5 @@ +import { SNNote, SNTag, ItemCounts } from '@standardnotes/models' + +export interface ItemCounterInterface { + countNotesAndTags(items: Array): ItemCounts +} diff --git a/packages/services/src/Domain/index.ts b/packages/services/src/Domain/index.ts index 856c2656a..94aae54f7 100644 --- a/packages/services/src/Domain/index.ts +++ b/packages/services/src/Domain/index.ts @@ -50,6 +50,8 @@ export * from './Internal/InternalEventHandlerInterface' export * from './Internal/InternalEventInterface' export * from './Internal/InternalEventPublishStrategy' export * from './Internal/InternalEventType' +export * from './Item/ItemCounter' +export * from './Item/ItemCounterInterface' export * from './Item/ItemManagerInterface' export * from './Item/ItemsClientInterface' export * from './Item/ItemsServerInterface' diff --git a/packages/web/src/javascripts/Controllers/AccountMenu/AccountMenuController.ts b/packages/web/src/javascripts/Controllers/AccountMenu/AccountMenuController.ts index 9e2128d21..99edfeeaf 100644 --- a/packages/web/src/javascripts/Controllers/AccountMenu/AccountMenuController.ts +++ b/packages/web/src/javascripts/Controllers/AccountMenu/AccountMenuController.ts @@ -1,10 +1,17 @@ import { destroyAllObjectProperties, isDev } from '@/Utils' import { action, computed, makeObservable, observable, runInAction } from 'mobx' -import { ApplicationEvent, ContentType, InternalEventBus, SNNote, SNTag } from '@standardnotes/snjs' +import { + ApplicationEvent, + ContentType, + InternalEventBus, + SNNote, + SNTag, + ItemCounterInterface, + ItemCounts, +} from '@standardnotes/snjs' import { WebApplication } from '@/Application/Application' import { AccountMenuPane } from '@/Components/AccountMenu/AccountMenuPane' import { AbstractViewController } from '../Abstract/AbstractViewController' -import { StructuredItemsCount } from './StructuredItemsCount' export class AccountMenuController extends AbstractViewController { show = false @@ -28,7 +35,7 @@ export class AccountMenuController extends AbstractViewController { destroyAllObjectProperties(this) } - constructor(application: WebApplication, eventBus: InternalEventBus) { + constructor(application: WebApplication, eventBus: InternalEventBus, private itemCounter: ItemCounterInterface) { super(application, eventBus) makeObservable(this, { @@ -152,30 +159,7 @@ export class AccountMenuController extends AbstractViewController { return this.notesAndTags.length } - get structuredNotesAndTagsCount(): StructuredItemsCount { - const count: StructuredItemsCount = { - notes: 0, - archived: 0, - deleted: 0, - tags: 0, - } - for (const item of this.notesAndTags) { - if (item.archived) { - count.archived++ - } - - if (item.trashed) { - count.deleted++ - } - - if (item.content_type === ContentType.Note) { - count.notes++ - } - - if (item.content_type === ContentType.Tag) { - count.tags++ - } - } - return count + get structuredNotesAndTagsCount(): ItemCounts { + return this.itemCounter.countNotesAndTags(this.notesAndTags) } } diff --git a/packages/web/src/javascripts/Controllers/ViewControllerManager.ts b/packages/web/src/javascripts/Controllers/ViewControllerManager.ts index cfda20dac..f1541d567 100644 --- a/packages/web/src/javascripts/Controllers/ViewControllerManager.ts +++ b/packages/web/src/javascripts/Controllers/ViewControllerManager.ts @@ -2,7 +2,14 @@ import { storage, StorageKey } from '@standardnotes/ui-services' import { WebApplication } from '@/Application/Application' import { AccountMenuController } from '@/Controllers/AccountMenu/AccountMenuController' import { destroyAllObjectProperties } from '@/Utils' -import { ApplicationEvent, DeinitSource, WebOrDesktopDeviceInterface, InternalEventBus } from '@standardnotes/snjs' +import { + ApplicationEvent, + DeinitSource, + WebOrDesktopDeviceInterface, + InternalEventBus, + ItemCounterInterface, + ItemCounter, +} from '@standardnotes/snjs' import { action, makeObservable, observable } from 'mobx' import { ActionsMenuController } from './ActionsMenuController' import { FeaturesController } from './FeaturesController' @@ -52,10 +59,13 @@ export class ViewControllerManager { private appEventObserverRemovers: (() => void)[] = [] private eventBus: InternalEventBus + private itemCounter: ItemCounterInterface constructor(public application: WebApplication, private device: WebOrDesktopDeviceInterface) { this.eventBus = new InternalEventBus() + this.itemCounter = new ItemCounter() + this.selectionController = new SelectedItemsController(application, this.eventBus) this.noteTagsController = new NoteTagsController(application, this.eventBus) @@ -90,7 +100,7 @@ export class ViewControllerManager { this.noAccountWarningController = new NoAccountWarningController(application, this.eventBus) - this.accountMenuController = new AccountMenuController(application, this.eventBus) + this.accountMenuController = new AccountMenuController(application, this.eventBus, this.itemCounter) this.subscriptionController = new SubscriptionController(application, this.eventBus)