From a5b1d5c278a771af88fc43f2c610d4ec724db659 Mon Sep 17 00:00:00 2001 From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> Date: Sun, 3 Jul 2022 00:49:22 +0600 Subject: [PATCH] Fix role migration, remove extra rosamunds (#2190) Signed-off-by: Andrey Sobolev Co-authored-by: Andrey Sobolev --- models/contact/src/migration.ts | 3 +- models/demo/src/migration.ts | 38 ++++++++++++++----- models/notification/src/index.ts | 1 + .../presentation/src/components/Card.svelte | 2 +- plugins/contact-assets/lang/en.json | 3 +- plugins/contact-assets/lang/ru.json | 3 +- .../src/components/ContactPresenter.svelte | 15 +++++++- .../src/components/EmployeePresenter.svelte | 8 ++-- plugins/contact-resources/src/plugin.ts | 3 +- .../src/components/Applications.svelte | 2 +- .../src/components/Owners.svelte | 9 ++++- .../src/components/WorkspaceSettings.svelte | 20 +++++++--- .../src/components/NewIssueHeader.svelte | 6 ++- .../src/components/ProjectSelector.svelte | 19 +++------- .../src/components/ClassAttributeBar.svelte | 5 ++- server/account/src/index.ts | 3 +- tests/sanity/tests/recruit.spec.ts | 2 +- tests/sanity/tests/settings.spec.ts | 9 +++-- tests/sanity/tests/tracker.spec.ts | 1 + tests/sanity/tests/utils.ts | 2 +- 20 files changed, 102 insertions(+), 52 deletions(-) diff --git a/models/contact/src/migration.ts b/models/contact/src/migration.ts index f493ea4d7f..9762088643 100644 --- a/models/contact/src/migration.ts +++ b/models/contact/src/migration.ts @@ -88,7 +88,8 @@ async function setRole (client: MigrationClient): Promise { DOMAIN_TX, { _class: core.class.TxCreateDoc, - objectClass: contact.class.Employee + objectClass: contact.class.EmployeeAccount, + 'attributes.role': { $exists: false } }, { 'attributes.role': AccountRole.User diff --git a/models/demo/src/migration.ts b/models/demo/src/migration.ts index cc9331cdeb..dbe9b35b9b 100644 --- a/models/demo/src/migration.ts +++ b/models/demo/src/migration.ts @@ -13,10 +13,11 @@ // limitations under the License. // -import core, { AccountRole, TxOperations } from '@anticrm/core' +import core, { AccountRole, DOMAIN_TX, TxCreateDoc, TxOperations } from '@anticrm/core' import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model' import contact, { EmployeeAccount } from '@anticrm/contact' import recruit from '@anticrm/model-recruit' +import { DOMAIN_CONTACT } from '@anticrm/model-contact' async function createCandidate ( tx: TxOperations, @@ -45,20 +46,37 @@ async function createCandidate ( } export const demoOperation: MigrateOperation = { - async migrate (client: MigrationClient): Promise {}, + async migrate (client: MigrationClient): Promise { + const rosamunds = await client.find>(DOMAIN_TX, { + _class: core.class.TxCreateDoc, + objectClass: contact.class.EmployeeAccount, + 'attributes.email': 'rosamund@hc.engineering' + }) + const docs = await client.find(DOMAIN_CONTACT, { + _id: { $in: rosamunds.map((p) => p.attributes.employee) } + }) + const currentEmployees = new Set(docs.map((p) => p._id)) + for (const rosamund of rosamunds) { + if (!currentEmployees.has(rosamund.attributes.employee)) await client.delete(DOMAIN_TX, rosamund._id) + } + }, async upgrade (client: MigrationUpgradeClient): Promise { - const tx = new TxOperations(client, core.account.System) - const current = await tx.findOne(contact.class.EmployeeAccount, { + const ops = new TxOperations(client, core.account.System) + const tx = await ops.findOne(core.class.TxCreateDoc, { + objectClass: contact.class.EmployeeAccount, + 'attributes.email': 'rosamund@hc.engineering' + }) + const current = await ops.findOne(contact.class.EmployeeAccount, { email: 'rosamund@hc.engineering' }) - if (current === undefined) { - const employee = await tx.createDoc(contact.class.Employee, contact.space.Employee, { + if (tx === undefined && current === undefined) { + const employee = await ops.createDoc(contact.class.Employee, contact.space.Employee, { name: 'Chen,Rosamund', city: 'Mountain View', active: true }) - await tx.createDoc(contact.class.EmployeeAccount, core.space.Model, { + await ops.createDoc(contact.class.EmployeeAccount, core.space.Model, { email: 'rosamund@hc.engineering', employee, name: 'Chen,Rosamund', @@ -66,8 +84,8 @@ export const demoOperation: MigrateOperation = { }) } - await createCandidate(tx, 'P.,Andrey', 'Monte Carlo', 'andrey@hc.engineering', 'Chief Architect') - await createCandidate(tx, 'M.,Marina', 'Los Angeles', 'marina@hc.engineering', 'Chief Designer') - await createCandidate(tx, 'P.,Alex', 'Krasnodar, Russia', 'alex@hc.engineering', 'Frontend Engineer') + await createCandidate(ops, 'P.,Andrey', 'Monte Carlo', 'andrey@hc.engineering', 'Chief Architect') + await createCandidate(ops, 'M.,Marina', 'Los Angeles', 'marina@hc.engineering', 'Chief Designer') + await createCandidate(ops, 'P.,Alex', 'Krasnodar, Russia', 'alex@hc.engineering', 'Frontend Engineer') } } diff --git a/models/notification/src/index.ts b/models/notification/src/index.ts index 9f34e9ece0..e630099cba 100644 --- a/models/notification/src/index.ts +++ b/models/notification/src/index.ts @@ -170,6 +170,7 @@ export function createModel (builder: Builder): void { icon: notification.icon.Notifications, component: notification.component.NotificationSettings, group: 'settings', + secured: false, order: 2500 }, notification.ids.NotificationSettings diff --git a/packages/presentation/src/components/Card.svelte b/packages/presentation/src/components/Card.svelte index 2467e2ce80..eaf38d0b65 100644 --- a/packages/presentation/src/components/Card.svelte +++ b/packages/presentation/src/components/Card.svelte @@ -84,7 +84,7 @@ } okProcessing = true const r = okAction() - if (r instanceof Promise && !createMore) { + if (r instanceof Promise && createMore) { r.then(() => { okProcessing = false dispatch('close') diff --git a/plugins/contact-assets/lang/en.json b/plugins/contact-assets/lang/en.json index e9470046a0..8d08c623ee 100644 --- a/plugins/contact-assets/lang/en.json +++ b/plugins/contact-assets/lang/en.json @@ -67,6 +67,7 @@ "KickEmployee": "Kick an employee", "KickEmployeeDescr": "Are you sure you want to kick the employee out of the workspace? This action cannot be undone", "Email": "Email", - "CreateEmployee": "Create an employee" + "CreateEmployee": "Create an employee", + "Inactive": "Inactive" } } \ No newline at end of file diff --git a/plugins/contact-assets/lang/ru.json b/plugins/contact-assets/lang/ru.json index c1aae20f64..4afcdf6387 100644 --- a/plugins/contact-assets/lang/ru.json +++ b/plugins/contact-assets/lang/ru.json @@ -67,6 +67,7 @@ "KickEmployee": "Исключить сотрудника", "KickEmployeeDescr": "Вы действительно хотите выгнать сотрудника из рабочего пространства? Это действие нельзя отменить", "Email": "Email", - "CreateEmployee": "Создать сотрудника" + "CreateEmployee": "Создать сотрудника", + "Inactive": "Не активный" } } \ No newline at end of file diff --git a/plugins/contact-resources/src/components/ContactPresenter.svelte b/plugins/contact-resources/src/components/ContactPresenter.svelte index 6d22e38452..0adcaf9bcc 100644 --- a/plugins/contact-resources/src/components/ContactPresenter.svelte +++ b/plugins/contact-resources/src/components/ContactPresenter.svelte @@ -14,8 +14,10 @@ // limitations under the License. --> {#if isPerson(value)} + {#if isEmployee(value) && toEmployee(value)?.active === false} +
+ (
+ {/if} {:else} {/if} diff --git a/plugins/contact-resources/src/components/EmployeePresenter.svelte b/plugins/contact-resources/src/components/EmployeePresenter.svelte index 4c658e6f67..68ff9fffbc 100644 --- a/plugins/contact-resources/src/components/EmployeePresenter.svelte +++ b/plugins/contact-resources/src/components/EmployeePresenter.svelte @@ -1,12 +1,12 @@ @@ -60,7 +70,7 @@ label={category.label} selected={category.name === categoryId} on:click={() => { - selectCategory(category) + selectCategory(category.name) }} /> {/each} diff --git a/plugins/tracker-resources/src/components/NewIssueHeader.svelte b/plugins/tracker-resources/src/components/NewIssueHeader.svelte index 8f7be42e3c..d1c621db3a 100644 --- a/plugins/tracker-resources/src/components/NewIssueHeader.svelte +++ b/plugins/tracker-resources/src/components/NewIssueHeader.svelte @@ -37,9 +37,11 @@ } async function newIssue (): Promise { - if (space) { - showPopup(CreateIssue, { space }, 'top') + if (!space) { + const team = await client.findOne(tracker.class.Team, {}) + space = team?._id } + showPopup(CreateIssue, { space }, 'top') } diff --git a/plugins/tracker-resources/src/components/ProjectSelector.svelte b/plugins/tracker-resources/src/components/ProjectSelector.svelte index 0249788436..26bf29d9ba 100644 --- a/plugins/tracker-resources/src/components/ProjectSelector.svelte +++ b/plugins/tracker-resources/src/components/ProjectSelector.svelte @@ -36,39 +36,32 @@ let defaultProjectLabel = '' const query = createQuery() - let projects: Map, Project> = new Map, Project>() + let rawProjects: Project[] = [] query.query( tracker.class.Project, {}, (res) => { - projects = new Map( - res.map((p) => { - return [p._id, p] - }) - ) + rawProjects = res }, { sort: { modifiedOn: SortingOrder.Ascending } } ) - $: handleSelectedProjectIdUpdated(value, projects) + $: handleSelectedProjectIdUpdated(value, rawProjects) $: translate(tracker.string.Project, {}).then((result) => (defaultProjectLabel = result)) $: projectIcon = selectedProject?.icon ?? tracker.icon.Projects $: projectText = shouldShowLabel ? selectedProject?.label ?? defaultProjectLabel : undefined - const handleSelectedProjectIdUpdated = async ( - newProjectId: Ref | null | undefined, - projects: Map, Project> - ) => { + const handleSelectedProjectIdUpdated = async (newProjectId: Ref | null | undefined, projects: Project[]) => { if (newProjectId === null || newProjectId === undefined) { selectedProject = undefined return } - selectedProject = projects.get(newProjectId) + selectedProject = projects.find((it) => it._id === newProjectId) } const handleProjectEditorOpened = async (event: MouseEvent): Promise => { @@ -79,7 +72,7 @@ const projectsInfo = [ { id: null, icon: tracker.icon.Projects, label: tracker.string.NoProject }, - ...Array.from(projects.values()).map((p) => ({ + ...rawProjects.map((p) => ({ id: p._id, icon: p.icon, text: p.label diff --git a/plugins/view-resources/src/components/ClassAttributeBar.svelte b/plugins/view-resources/src/components/ClassAttributeBar.svelte index e7349db141..9bf57b4157 100644 --- a/plugins/view-resources/src/components/ClassAttributeBar.svelte +++ b/plugins/view-resources/src/components/ClassAttributeBar.svelte @@ -66,8 +66,9 @@ ev.stopPropagation() const loc = getCurrentLocation() loc.path[1] = settingId - loc.path[2] = 'classes' - loc.path.length = 3 + loc.path[2] = 'setting' + loc.path[3] = 'classes' + loc.path.length = 4 loc.query = { _class } loc.fragment = undefined navigate(loc) diff --git a/server/account/src/index.ts b/server/account/src/index.ts index c89f785a0a..5c82b656b6 100644 --- a/server/account/src/index.ts +++ b/server/account/src/index.ts @@ -457,8 +457,9 @@ export async function setRole (email: string, workspace: string, role: AccountRo const existingAccount = await ops.findOne(contact.class.EmployeeAccount, { email }) if (existingAccount !== undefined) { + const value = isNaN(Number(role)) ? 0 : Number(role) await ops.update(existingAccount, { - role + role: value }) } } finally { diff --git a/tests/sanity/tests/recruit.spec.ts b/tests/sanity/tests/recruit.spec.ts index 3bfd09d4cc..273d2e40c7 100644 --- a/tests/sanity/tests/recruit.spec.ts +++ b/tests/sanity/tests/recruit.spec.ts @@ -78,7 +78,7 @@ test.describe('recruit tests', () => { // Click on Add button // await page.click('.applications-container .flex-row-center .flex-center') - await page.click('text=Applications There are no applications for this talent. New Application >> button') + await page.click('button[id="appls.add"]') await page.click('button:has-text("Vacancy")') diff --git a/tests/sanity/tests/settings.spec.ts b/tests/sanity/tests/settings.spec.ts index f78ec38546..c98c6ed65e 100644 --- a/tests/sanity/tests/settings.spec.ts +++ b/tests/sanity/tests/settings.spec.ts @@ -44,13 +44,13 @@ test.describe('contact tests', () => { // Click button:has-text("Settings") await page.hover('button:has-text("Settings")') await page.click('button:has-text("Settings")') - // Click text=Workspace Integrations >> button - await page.click('text=Workspace Integrations >> button') + // Click text=Workspace Notifications >> button + await page.click('text=Workspace Notifications >> button') await page.click('text=Templates') // Click .flex-center.icon-button await page.click('#create-template >> .flex-center.icon-button') // Click [placeholder="New\ template"] - await page.click('[placeholder="New\\ template"]') + // await page.click('[placeholder="New\\ template"]') // Fill [placeholder="New\ template"] await page.fill('[placeholder="New\\ template"]', 't1') @@ -77,7 +77,8 @@ test.describe('contact tests', () => { // await page.click('text=Workspace') await page.hover('button:has-text("Settings")') await page.click('button:has-text("Settings")') - await page.click('text=Workspace Integrations >> button') + // Click text=Workspace Notifications >> button + await page.click('text=Workspace Notifications >> button') // Click button:has-text("Manage Statuses") await page.click('text="Manage Statuses"') // Click text=Vacancies diff --git a/tests/sanity/tests/tracker.spec.ts b/tests/sanity/tests/tracker.spec.ts index 3bd168e0f5..1c9f708212 100644 --- a/tests/sanity/tests/tracker.spec.ts +++ b/tests/sanity/tests/tracker.spec.ts @@ -49,6 +49,7 @@ async function fillIssueForm ( } async function createIssue (page: Page, props: IssueProps): Promise { + await page.waitForSelector('span:has-text("Default")') await page.click('button:has-text("New issue")') await fillIssueForm(page, props) await page.click('button:has-text("Save issue")') diff --git a/tests/sanity/tests/utils.ts b/tests/sanity/tests/utils.ts index f24cf5467d..05e6d9d227 100644 --- a/tests/sanity/tests/utils.ts +++ b/tests/sanity/tests/utils.ts @@ -12,7 +12,7 @@ function toHex (value: number, chars: number): string { return result } -let counter = (Math.random() * (1 << 24)) | 0 +let counter = 0 const random = toHex((Math.random() * (1 << 24)) | 0, 6) + toHex((Math.random() * (1 << 16)) | 0, 4) function timestamp (): string {