mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
Fix role migration, remove extra rosamunds (#2190)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com> Co-authored-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
a4b3cb4a44
commit
a5b1d5c278
@ -88,7 +88,8 @@ async function setRole (client: MigrationClient): Promise<void> {
|
|||||||
DOMAIN_TX,
|
DOMAIN_TX,
|
||||||
{
|
{
|
||||||
_class: core.class.TxCreateDoc,
|
_class: core.class.TxCreateDoc,
|
||||||
objectClass: contact.class.Employee
|
objectClass: contact.class.EmployeeAccount,
|
||||||
|
'attributes.role': { $exists: false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'attributes.role': AccountRole.User
|
'attributes.role': AccountRole.User
|
||||||
|
@ -13,10 +13,11 @@
|
|||||||
// limitations under the License.
|
// 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 { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
|
||||||
import contact, { EmployeeAccount } from '@anticrm/contact'
|
import contact, { EmployeeAccount } from '@anticrm/contact'
|
||||||
import recruit from '@anticrm/model-recruit'
|
import recruit from '@anticrm/model-recruit'
|
||||||
|
import { DOMAIN_CONTACT } from '@anticrm/model-contact'
|
||||||
|
|
||||||
async function createCandidate (
|
async function createCandidate (
|
||||||
tx: TxOperations,
|
tx: TxOperations,
|
||||||
@ -45,20 +46,37 @@ async function createCandidate (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const demoOperation: MigrateOperation = {
|
export const demoOperation: MigrateOperation = {
|
||||||
async migrate (client: MigrationClient): Promise<void> {},
|
async migrate (client: MigrationClient): Promise<void> {
|
||||||
|
const rosamunds = await client.find<TxCreateDoc<EmployeeAccount>>(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<void> {
|
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
||||||
const tx = new TxOperations(client, core.account.System)
|
const ops = new TxOperations(client, core.account.System)
|
||||||
const current = await tx.findOne(contact.class.EmployeeAccount, {
|
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'
|
email: 'rosamund@hc.engineering'
|
||||||
})
|
})
|
||||||
if (current === undefined) {
|
if (tx === undefined && current === undefined) {
|
||||||
const employee = await tx.createDoc(contact.class.Employee, contact.space.Employee, {
|
const employee = await ops.createDoc(contact.class.Employee, contact.space.Employee, {
|
||||||
name: 'Chen,Rosamund',
|
name: 'Chen,Rosamund',
|
||||||
city: 'Mountain View',
|
city: 'Mountain View',
|
||||||
active: true
|
active: true
|
||||||
})
|
})
|
||||||
|
|
||||||
await tx.createDoc<EmployeeAccount>(contact.class.EmployeeAccount, core.space.Model, {
|
await ops.createDoc<EmployeeAccount>(contact.class.EmployeeAccount, core.space.Model, {
|
||||||
email: 'rosamund@hc.engineering',
|
email: 'rosamund@hc.engineering',
|
||||||
employee,
|
employee,
|
||||||
name: 'Chen,Rosamund',
|
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(ops, 'P.,Andrey', 'Monte Carlo', 'andrey@hc.engineering', 'Chief Architect')
|
||||||
await createCandidate(tx, 'M.,Marina', 'Los Angeles', 'marina@hc.engineering', 'Chief Designer')
|
await createCandidate(ops, '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.,Alex', 'Krasnodar, Russia', 'alex@hc.engineering', 'Frontend Engineer')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,7 @@ export function createModel (builder: Builder): void {
|
|||||||
icon: notification.icon.Notifications,
|
icon: notification.icon.Notifications,
|
||||||
component: notification.component.NotificationSettings,
|
component: notification.component.NotificationSettings,
|
||||||
group: 'settings',
|
group: 'settings',
|
||||||
|
secured: false,
|
||||||
order: 2500
|
order: 2500
|
||||||
},
|
},
|
||||||
notification.ids.NotificationSettings
|
notification.ids.NotificationSettings
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
}
|
}
|
||||||
okProcessing = true
|
okProcessing = true
|
||||||
const r = okAction()
|
const r = okAction()
|
||||||
if (r instanceof Promise && !createMore) {
|
if (r instanceof Promise && createMore) {
|
||||||
r.then(() => {
|
r.then(() => {
|
||||||
okProcessing = false
|
okProcessing = false
|
||||||
dispatch('close')
|
dispatch('close')
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
"KickEmployee": "Kick an employee",
|
"KickEmployee": "Kick an employee",
|
||||||
"KickEmployeeDescr": "Are you sure you want to kick the employee out of the workspace? This action cannot be undone",
|
"KickEmployeeDescr": "Are you sure you want to kick the employee out of the workspace? This action cannot be undone",
|
||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"CreateEmployee": "Create an employee"
|
"CreateEmployee": "Create an employee",
|
||||||
|
"Inactive": "Inactive"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -67,6 +67,7 @@
|
|||||||
"KickEmployee": "Исключить сотрудника",
|
"KickEmployee": "Исключить сотрудника",
|
||||||
"KickEmployeeDescr": "Вы действительно хотите выгнать сотрудника из рабочего пространства? Это действие нельзя отменить",
|
"KickEmployeeDescr": "Вы действительно хотите выгнать сотрудника из рабочего пространства? Это действие нельзя отменить",
|
||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"CreateEmployee": "Создать сотрудника"
|
"CreateEmployee": "Создать сотрудника",
|
||||||
|
"Inactive": "Не активный"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,8 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Contact, Organization } from '@anticrm/contact'
|
import { Contact, Employee, Organization } from '@anticrm/contact'
|
||||||
import { getClient } from '@anticrm/presentation'
|
import { getClient } from '@anticrm/presentation'
|
||||||
|
import { Label } from '@anticrm/ui'
|
||||||
|
import contact from '../plugin'
|
||||||
|
|
||||||
import OrganizationPresenter from './OrganizationPresenter.svelte'
|
import OrganizationPresenter from './OrganizationPresenter.svelte'
|
||||||
import PersonPresenter from './PersonPresenter.svelte'
|
import PersonPresenter from './PersonPresenter.svelte'
|
||||||
@ -28,11 +30,22 @@
|
|||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
return hierarchy.isDerived(value._class, contact.class.Person)
|
return hierarchy.isDerived(value._class, contact.class.Person)
|
||||||
}
|
}
|
||||||
|
function isEmployee (value: Contact): boolean {
|
||||||
|
const client = getClient()
|
||||||
|
const hierarchy = client.getHierarchy()
|
||||||
|
return hierarchy.isDerived(value._class, contact.class.Employee)
|
||||||
|
}
|
||||||
const toOrg = (contact: Contact) => contact as Organization
|
const toOrg = (contact: Contact) => contact as Organization
|
||||||
|
const toEmployee = (contact: Contact) => contact as Employee
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isPerson(value)}
|
{#if isPerson(value)}
|
||||||
<PersonPresenter {isInteractive} {value} />
|
<PersonPresenter {isInteractive} {value} />
|
||||||
|
{#if isEmployee(value) && toEmployee(value)?.active === false}
|
||||||
|
<div class="ml-1">
|
||||||
|
(<Label label={contact.string.Inactive} />)
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<OrganizationPresenter value={toOrg(value)} />
|
<OrganizationPresenter value={toOrg(value)} />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Employee } from '@anticrm/contact'
|
import { Employee } from '@anticrm/contact'
|
||||||
import EmployeeStatusPresenter from './EmployeeStatusPresenter.svelte'
|
|
||||||
import PersonPresenter from '../components/PersonPresenter.svelte'
|
|
||||||
import { showPopup } from '@anticrm/ui'
|
|
||||||
import EmployeePreviewPopup from './EmployeePreviewPopup.svelte'
|
|
||||||
import { WithLookup } from '@anticrm/core'
|
import { WithLookup } from '@anticrm/core'
|
||||||
import { IntlString } from '@anticrm/platform'
|
import { IntlString } from '@anticrm/platform'
|
||||||
import type { AnyComponent, AnySvelteComponent } from '@anticrm/ui'
|
import type { AnyComponent, AnySvelteComponent } from '@anticrm/ui'
|
||||||
|
import { showPopup } from '@anticrm/ui'
|
||||||
|
import PersonPresenter from '../components/PersonPresenter.svelte'
|
||||||
|
import EmployeePreviewPopup from './EmployeePreviewPopup.svelte'
|
||||||
|
import EmployeeStatusPresenter from './EmployeeStatusPresenter.svelte'
|
||||||
|
|
||||||
export let value: WithLookup<Employee> | null | undefined
|
export let value: WithLookup<Employee> | null | undefined
|
||||||
export let tooltipLabels:
|
export let tooltipLabels:
|
||||||
|
@ -60,6 +60,7 @@ export default mergeIds(contactId, contact, {
|
|||||||
KickEmployee: '' as IntlString,
|
KickEmployee: '' as IntlString,
|
||||||
KickEmployeeDescr: '' as IntlString,
|
KickEmployeeDescr: '' as IntlString,
|
||||||
Email: '' as IntlString,
|
Email: '' as IntlString,
|
||||||
CreateEmployee: '' as IntlString
|
CreateEmployee: '' as IntlString,
|
||||||
|
Inactive: '' as IntlString
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
<span class="antiSection-header__title">
|
<span class="antiSection-header__title">
|
||||||
<Label label={recruit.string.Applications} />
|
<Label label={recruit.string.Applications} />
|
||||||
</span>
|
</span>
|
||||||
<Button icon={IconAdd} kind={'transparent'} shape={'circle'} on:click={createApp} />
|
<Button id="appls.add" icon={IconAdd} kind={'transparent'} shape={'circle'} on:click={createApp} />
|
||||||
</div>
|
</div>
|
||||||
{#if applications > 0}
|
{#if applications > 0}
|
||||||
<Table
|
<Table
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee, EmployeeAccount } from '@anticrm/contact'
|
import contact, { Employee, EmployeeAccount, formatName } from '@anticrm/contact'
|
||||||
import { PersonPresenter } from '@anticrm/contact-resources'
|
import { PersonPresenter } from '@anticrm/contact-resources'
|
||||||
import { AccountRole, getCurrentAccount, Ref, SortingOrder } from '@anticrm/core'
|
import { AccountRole, getCurrentAccount, Ref, SortingOrder } from '@anticrm/core'
|
||||||
import { createQuery, getClient } from '@anticrm/presentation'
|
import { createQuery, getClient } from '@anticrm/presentation'
|
||||||
@ -71,8 +71,13 @@
|
|||||||
<div class="ac-body columns">
|
<div class="ac-body columns">
|
||||||
<div class="ac-column max">
|
<div class="ac-column max">
|
||||||
{#each accounts as account (account._id)}
|
{#each accounts as account (account._id)}
|
||||||
|
{@const employee = employees.get(account.employee)}
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<PersonPresenter value={employees.get(account.employee)} isInteractive={false} />
|
{#if employee}
|
||||||
|
<PersonPresenter value={employee} isInteractive={false} />
|
||||||
|
{:else}
|
||||||
|
{formatName(account.name)}
|
||||||
|
{/if}
|
||||||
<DropdownLabelsIntl
|
<DropdownLabelsIntl
|
||||||
label={setting.string.Role}
|
label={setting.string.Role}
|
||||||
disabled={account.role > currentRole || (account.role === AccountRole.Owner && owners.length === 1)}
|
disabled={account.role > currentRole || (account.role === AccountRole.Owner && owners.length === 1)}
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
import { AccountRole, getCurrentAccount } from '@anticrm/core'
|
import { AccountRole, getCurrentAccount } from '@anticrm/core'
|
||||||
import { createQuery } from '@anticrm/presentation'
|
import { createQuery } from '@anticrm/presentation'
|
||||||
import setting, { SettingsCategory } from '@anticrm/setting'
|
import setting, { SettingsCategory } from '@anticrm/setting'
|
||||||
import { Component, Label } from '@anticrm/ui'
|
import { Component, getCurrentLocation, Label, location, navigate } from '@anticrm/ui'
|
||||||
|
import { onDestroy } from 'svelte'
|
||||||
import CategoryElement from './CategoryElement.svelte'
|
import CategoryElement from './CategoryElement.svelte'
|
||||||
|
|
||||||
let category: SettingsCategory | undefined
|
let category: SettingsCategory | undefined
|
||||||
@ -41,9 +42,18 @@
|
|||||||
return categories.find((x) => x.name === name)
|
return categories.find((x) => x.name === name)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCategory (value: SettingsCategory) {
|
onDestroy(
|
||||||
categoryId = value.name
|
location.subscribe(async (loc) => {
|
||||||
category = value
|
categoryId = loc.path[3]
|
||||||
|
category = findCategory(categoryId)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
function selectCategory (id: string): void {
|
||||||
|
const loc = getCurrentLocation()
|
||||||
|
loc.path[3] = id
|
||||||
|
loc.path.length = 4
|
||||||
|
navigate(loc)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -60,7 +70,7 @@
|
|||||||
label={category.label}
|
label={category.label}
|
||||||
selected={category.name === categoryId}
|
selected={category.name === categoryId}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
selectCategory(category)
|
selectCategory(category.name)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -37,9 +37,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function newIssue (): Promise<void> {
|
async function newIssue (): Promise<void> {
|
||||||
if (space) {
|
if (!space) {
|
||||||
showPopup(CreateIssue, { space }, 'top')
|
const team = await client.findOne(tracker.class.Team, {})
|
||||||
|
space = team?._id
|
||||||
}
|
}
|
||||||
|
showPopup(CreateIssue, { space }, 'top')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -36,39 +36,32 @@
|
|||||||
let defaultProjectLabel = ''
|
let defaultProjectLabel = ''
|
||||||
|
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
let projects: Map<Ref<Project>, Project> = new Map<Ref<Project>, Project>()
|
let rawProjects: Project[] = []
|
||||||
query.query(
|
query.query(
|
||||||
tracker.class.Project,
|
tracker.class.Project,
|
||||||
{},
|
{},
|
||||||
(res) => {
|
(res) => {
|
||||||
projects = new Map(
|
rawProjects = res
|
||||||
res.map((p) => {
|
|
||||||
return [p._id, p]
|
|
||||||
})
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sort: { modifiedOn: SortingOrder.Ascending }
|
sort: { modifiedOn: SortingOrder.Ascending }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
$: handleSelectedProjectIdUpdated(value, projects)
|
$: handleSelectedProjectIdUpdated(value, rawProjects)
|
||||||
|
|
||||||
$: translate(tracker.string.Project, {}).then((result) => (defaultProjectLabel = result))
|
$: translate(tracker.string.Project, {}).then((result) => (defaultProjectLabel = result))
|
||||||
$: projectIcon = selectedProject?.icon ?? tracker.icon.Projects
|
$: projectIcon = selectedProject?.icon ?? tracker.icon.Projects
|
||||||
$: projectText = shouldShowLabel ? selectedProject?.label ?? defaultProjectLabel : undefined
|
$: projectText = shouldShowLabel ? selectedProject?.label ?? defaultProjectLabel : undefined
|
||||||
|
|
||||||
const handleSelectedProjectIdUpdated = async (
|
const handleSelectedProjectIdUpdated = async (newProjectId: Ref<Project> | null | undefined, projects: Project[]) => {
|
||||||
newProjectId: Ref<Project> | null | undefined,
|
|
||||||
projects: Map<Ref<Project>, Project>
|
|
||||||
) => {
|
|
||||||
if (newProjectId === null || newProjectId === undefined) {
|
if (newProjectId === null || newProjectId === undefined) {
|
||||||
selectedProject = undefined
|
selectedProject = undefined
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedProject = projects.get(newProjectId)
|
selectedProject = projects.find((it) => it._id === newProjectId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleProjectEditorOpened = async (event: MouseEvent): Promise<void> => {
|
const handleProjectEditorOpened = async (event: MouseEvent): Promise<void> => {
|
||||||
@ -79,7 +72,7 @@
|
|||||||
|
|
||||||
const projectsInfo = [
|
const projectsInfo = [
|
||||||
{ id: null, icon: tracker.icon.Projects, label: tracker.string.NoProject },
|
{ id: null, icon: tracker.icon.Projects, label: tracker.string.NoProject },
|
||||||
...Array.from(projects.values()).map((p) => ({
|
...rawProjects.map((p) => ({
|
||||||
id: p._id,
|
id: p._id,
|
||||||
icon: p.icon,
|
icon: p.icon,
|
||||||
text: p.label
|
text: p.label
|
||||||
|
@ -66,8 +66,9 @@
|
|||||||
ev.stopPropagation()
|
ev.stopPropagation()
|
||||||
const loc = getCurrentLocation()
|
const loc = getCurrentLocation()
|
||||||
loc.path[1] = settingId
|
loc.path[1] = settingId
|
||||||
loc.path[2] = 'classes'
|
loc.path[2] = 'setting'
|
||||||
loc.path.length = 3
|
loc.path[3] = 'classes'
|
||||||
|
loc.path.length = 4
|
||||||
loc.query = { _class }
|
loc.query = { _class }
|
||||||
loc.fragment = undefined
|
loc.fragment = undefined
|
||||||
navigate(loc)
|
navigate(loc)
|
||||||
|
@ -457,8 +457,9 @@ export async function setRole (email: string, workspace: string, role: AccountRo
|
|||||||
const existingAccount = await ops.findOne(contact.class.EmployeeAccount, { email })
|
const existingAccount = await ops.findOne(contact.class.EmployeeAccount, { email })
|
||||||
|
|
||||||
if (existingAccount !== undefined) {
|
if (existingAccount !== undefined) {
|
||||||
|
const value = isNaN(Number(role)) ? 0 : Number(role)
|
||||||
await ops.update(existingAccount, {
|
await ops.update(existingAccount, {
|
||||||
role
|
role: value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -78,7 +78,7 @@ test.describe('recruit tests', () => {
|
|||||||
|
|
||||||
// Click on Add button
|
// Click on Add button
|
||||||
// await page.click('.applications-container .flex-row-center .flex-center')
|
// 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")')
|
await page.click('button:has-text("Vacancy")')
|
||||||
|
|
||||||
|
@ -44,13 +44,13 @@ test.describe('contact tests', () => {
|
|||||||
// Click button:has-text("Settings")
|
// Click button:has-text("Settings")
|
||||||
await page.hover('button:has-text("Settings")')
|
await page.hover('button:has-text("Settings")')
|
||||||
await page.click('button:has-text("Settings")')
|
await page.click('button:has-text("Settings")')
|
||||||
// Click text=Workspace Integrations >> button
|
// Click text=Workspace Notifications >> button
|
||||||
await page.click('text=Workspace Integrations >> button')
|
await page.click('text=Workspace Notifications >> button')
|
||||||
await page.click('text=Templates')
|
await page.click('text=Templates')
|
||||||
// Click .flex-center.icon-button
|
// Click .flex-center.icon-button
|
||||||
await page.click('#create-template >> .flex-center.icon-button')
|
await page.click('#create-template >> .flex-center.icon-button')
|
||||||
// Click [placeholder="New\ template"]
|
// Click [placeholder="New\ template"]
|
||||||
await page.click('[placeholder="New\\ template"]')
|
// await page.click('[placeholder="New\\ template"]')
|
||||||
// Fill [placeholder="New\ template"]
|
// Fill [placeholder="New\ template"]
|
||||||
await page.fill('[placeholder="New\\ template"]', 't1')
|
await page.fill('[placeholder="New\\ template"]', 't1')
|
||||||
|
|
||||||
@ -77,7 +77,8 @@ test.describe('contact tests', () => {
|
|||||||
// await page.click('text=Workspace')
|
// await page.click('text=Workspace')
|
||||||
await page.hover('button:has-text("Settings")')
|
await page.hover('button:has-text("Settings")')
|
||||||
await page.click('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")
|
// Click button:has-text("Manage Statuses")
|
||||||
await page.click('text="Manage Statuses"')
|
await page.click('text="Manage Statuses"')
|
||||||
// Click text=Vacancies
|
// Click text=Vacancies
|
||||||
|
@ -49,6 +49,7 @@ async function fillIssueForm (
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createIssue (page: Page, props: IssueProps): Promise<void> {
|
async function createIssue (page: Page, props: IssueProps): Promise<void> {
|
||||||
|
await page.waitForSelector('span:has-text("Default")')
|
||||||
await page.click('button:has-text("New issue")')
|
await page.click('button:has-text("New issue")')
|
||||||
await fillIssueForm(page, props)
|
await fillIssueForm(page, props)
|
||||||
await page.click('button:has-text("Save issue")')
|
await page.click('button:has-text("Save issue")')
|
||||||
|
@ -12,7 +12,7 @@ function toHex (value: number, chars: number): string {
|
|||||||
return result
|
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)
|
const random = toHex((Math.random() * (1 << 24)) | 0, 6) + toHex((Math.random() * (1 << 16)) | 0, 4)
|
||||||
|
|
||||||
function timestamp (): string {
|
function timestamp (): string {
|
||||||
|
Loading…
Reference in New Issue
Block a user