[UBER-323] "Create Project" fixes (#3296)

Signed-off-by: Sergei Ogorelkov <sergei.ogorelkov@icloud.com>
This commit is contained in:
Sergei Ogorelkov 2023-05-30 20:56:45 +04:00 committed by GitHub
parent dff77e1744
commit 314501a161
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 18 deletions

View File

@ -57,7 +57,8 @@
let description: string = project?.description ?? '' let description: string = project?.description ?? ''
let isPrivate: boolean = project?.private ?? false let isPrivate: boolean = project?.private ?? false
let icon: Asset | undefined = project?.icon ?? undefined let icon: Asset | undefined = project?.icon ?? undefined
let color: number | undefined = project?.color ?? undefined let color = project?.color ?? getColorNumberByText(name)
let isColorSelected = false
let defaultAssignee: Ref<Employee> | null | undefined = project?.defaultAssignee ?? null let defaultAssignee: Ref<Employee> | null | undefined = project?.defaultAssignee ?? null
let members: Ref<Account>[] = let members: Ref<Account>[] =
project?.members !== undefined ? hierarchy.clone(project.members) : [getCurrentAccount()._id] project?.members !== undefined ? hierarchy.clone(project.members) : [getCurrentAccount()._id]
@ -141,20 +142,14 @@
} }
} }
} }
if (Object.keys(update).length > 0) { if (Object.keys(update).length > 0) {
const ops = client.apply(project._id).notMatch(tracker.class.Project, { identifier: projectData.identifier })
isSaving = true isSaving = true
await ops.update(project, update) await client.update(project, update)
const succeeded = await ops.commit()
isSaving = false isSaving = false
if (succeeded) {
close()
} else {
changeIdentity(changeIdentityRef)
}
} }
close()
} }
async function createProject () { async function createProject () {
@ -209,10 +204,11 @@
} }
function chooseIcon (ev: MouseEvent) { function chooseIcon (ev: MouseEvent) {
showPopup(ProjectIconChooser, { icon, color: color ?? getColorNumberByText(name) }, 'top', (result) => { showPopup(ProjectIconChooser, { icon, color }, 'top', (result) => {
if (result !== undefined && result !== null) { if (result !== undefined && result !== null) {
icon = result.icon icon = result.icon
color = result.color color = result.color
isColorSelected = true
} }
}) })
} }
@ -263,6 +259,7 @@
on:input={() => { on:input={() => {
if (isNew) { if (isNew) {
identifier = name.toLocaleUpperCase().replaceAll(' ', '_').substring(0, 5) identifier = name.toLocaleUpperCase().replaceAll(' ', '_').substring(0, 5)
color = isColorSelected ? color : getColorNumberByText(name)
} }
}} }}
/> />

View File

@ -271,16 +271,11 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
return users.map((p) => p.email) return users.map((p) => p.email)
} }
async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> { private async getTxTargets (ctx: SessionContext, tx: Tx): Promise<string[] | undefined> {
const h = this.storage.hierarchy const h = this.storage.hierarchy
let targets: string[] | undefined let targets: string[] | undefined
if (h.isDerived(tx._class, core.class.TxCUD)) { if (h.isDerived(tx._class, core.class.TxCUD)) {
const cudTx = tx as TxCUD<Doc>
const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
if (isSpace) {
await this.handleTx(ctx, cudTx as TxCUD<Space>)
}
const account = await getUser(this.storage, ctx) const account = await getUser(this.storage, ctx)
if (tx.objectSpace === (account._id as string)) { if (tx.objectSpace === (account._id as string)) {
targets = [account.email] targets = [account.email]
@ -289,6 +284,8 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
if (space !== undefined) { if (space !== undefined) {
targets = await this.getTargets(space.members) targets = await this.getTargets(space.members)
if (!isOwner(account)) { if (!isOwner(account)) {
const cudTx = tx as TxCUD<Doc>
const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
const allowed = this.allowedSpaces[account._id] const allowed = this.allowedSpaces[account._id]
if (allowed === undefined || !allowed.includes(isSpace ? (cudTx.objectId as Ref<Space>) : tx.objectSpace)) { if (allowed === undefined || !allowed.includes(isSpace ? (cudTx.objectId as Ref<Space>) : tx.objectSpace)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {})) throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
@ -302,6 +299,19 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
} }
} }
} }
}
return targets
}
private async proccessTx (ctx: SessionContext, tx: Tx): Promise<void> {
const h = this.storage.hierarchy
if (h.isDerived(tx._class, core.class.TxCUD)) {
const cudTx = tx as TxCUD<Doc>
const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
if (isSpace) {
await this.handleTx(ctx, cudTx as TxCUD<Space>)
}
if (h.isDerived(cudTx.objectClass, core.class.Account) && cudTx._class === core.class.TxUpdateDoc) { if (h.isDerived(cudTx.objectClass, core.class.Account) && cudTx._class === core.class.TxUpdateDoc) {
const ctx = cudTx as TxUpdateDoc<Account> const ctx = cudTx as TxUpdateDoc<Account>
if (ctx.operations.role !== undefined) { if (ctx.operations.role !== undefined) {
@ -309,8 +319,15 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
} }
} }
} }
}
async tx (ctx: SessionContext, tx: Tx): Promise<TxMiddlewareResult> {
await this.proccessTx(ctx, tx)
const targets = await this.getTxTargets(ctx, tx)
const res = await this.provideTx(ctx, tx) const res = await this.provideTx(ctx, tx)
for (const tx of res[1]) {
await this.proccessTx(ctx, tx)
}
return [res[0], res[1], mergeTargets(targets, res[2])] return [res[0], res[1], mergeTargets(targets, res[2])]
} }