mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-30 20:25:38 +00:00
parent
9396f7ef20
commit
821ed6cd7b
@ -114,13 +114,11 @@ export function devTool (
|
|||||||
.command('create-account <email>')
|
.command('create-account <email>')
|
||||||
.description('create user and corresponding account in master database')
|
.description('create user and corresponding account in master database')
|
||||||
.requiredOption('-p, --password <password>', 'user password')
|
.requiredOption('-p, --password <password>', 'user password')
|
||||||
.requiredOption('-f, --first <first>', 'first name')
|
|
||||||
.requiredOption('-l, --last <last>', 'last name')
|
|
||||||
.action(async (email: string, cmd) => {
|
.action(async (email: string, cmd) => {
|
||||||
const { mongodbUri } = prepareTools()
|
const { mongodbUri } = prepareTools()
|
||||||
return await withDatabase(mongodbUri, async (db) => {
|
return await withDatabase(mongodbUri, async (db) => {
|
||||||
console.log(`creating account ${cmd.first as string} ${cmd.last as string} (${email})...`)
|
console.log(`creating account ${cmd.first as string} ${cmd.last as string} (${email})...`)
|
||||||
await createAcc(db, productId, email, cmd.password, cmd.first, cmd.last, true)
|
await createAcc(db, productId, email, cmd.password, true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -139,11 +137,13 @@ export function devTool (
|
|||||||
program
|
program
|
||||||
.command('assign-workspace <email> <workspace>')
|
.command('assign-workspace <email> <workspace>')
|
||||||
.description('assign workspace')
|
.description('assign workspace')
|
||||||
|
.requiredOption('-f, --first <first>', 'first name')
|
||||||
|
.requiredOption('-l, --last <last>', 'last name')
|
||||||
.action(async (email: string, workspace: string, cmd) => {
|
.action(async (email: string, workspace: string, cmd) => {
|
||||||
const { mongodbUri } = prepareTools()
|
const { mongodbUri } = prepareTools()
|
||||||
return await withDatabase(mongodbUri, async (db, client) => {
|
return await withDatabase(mongodbUri, async (db, client) => {
|
||||||
console.log(`assigning user ${email} to ${workspace}...`)
|
console.log(`assigning user ${email} to ${workspace}...`)
|
||||||
await assignWorkspace(db, productId, email, workspace)
|
await assignWorkspace(db, productId, email, workspace, cmd.first, cmd.last)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -90,7 +90,6 @@ export class TChannelProvider extends TDoc implements ChannelProvider {
|
|||||||
export class TContact extends TDoc implements Contact {
|
export class TContact extends TDoc implements Contact {
|
||||||
@Prop(TypeString(), contact.string.Name)
|
@Prop(TypeString(), contact.string.Name)
|
||||||
@Index(IndexKind.FullText)
|
@Index(IndexKind.FullText)
|
||||||
@Hidden()
|
|
||||||
name!: string
|
name!: string
|
||||||
|
|
||||||
avatar?: string | null
|
avatar?: string | null
|
||||||
@ -168,10 +167,6 @@ export class TEmployee extends TPerson implements Employee {
|
|||||||
@Hidden()
|
@Hidden()
|
||||||
statuses?: number
|
statuses?: number
|
||||||
|
|
||||||
@Prop(TypeString(), contact.string.DisplayName)
|
|
||||||
@Hidden()
|
|
||||||
displayName?: string | null
|
|
||||||
|
|
||||||
@Prop(TypeString(), contact.string.Position)
|
@Prop(TypeString(), contact.string.Position)
|
||||||
@Hidden()
|
@Hidden()
|
||||||
position?: string | null
|
position?: string | null
|
||||||
@ -293,6 +288,15 @@ export function createModel (builder: Builder): void {
|
|||||||
index: 100
|
index: 100
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
|
||||||
|
objectClass: contact.class.Person,
|
||||||
|
icon: contact.icon.Person,
|
||||||
|
txClass: core.class.TxUpdateDoc,
|
||||||
|
labelComponent: contact.activity.TxNameChange,
|
||||||
|
display: 'inline',
|
||||||
|
match: { 'operations.name': { $exists: true } }
|
||||||
|
})
|
||||||
|
|
||||||
builder.createDoc<Viewlet>(
|
builder.createDoc<Viewlet>(
|
||||||
view.class.Viewlet,
|
view.class.Viewlet,
|
||||||
core.space.Model,
|
core.space.Model,
|
||||||
|
@ -26,6 +26,9 @@ import type { AnyComponent } from '@hcengineering/ui'
|
|||||||
import { Action, ActionCategory, ViewAction } from '@hcengineering/view'
|
import { Action, ActionCategory, ViewAction } from '@hcengineering/view'
|
||||||
|
|
||||||
export default mergeIds(contactId, contact, {
|
export default mergeIds(contactId, contact, {
|
||||||
|
activity: {
|
||||||
|
TxNameChange: '' as AnyComponent
|
||||||
|
},
|
||||||
component: {
|
component: {
|
||||||
PersonPresenter: '' as AnyComponent,
|
PersonPresenter: '' as AnyComponent,
|
||||||
ContactRefPresenter: '' as AnyComponent,
|
ContactRefPresenter: '' as AnyComponent,
|
||||||
|
@ -139,7 +139,6 @@ export function createModel (builder: Builder): void {
|
|||||||
core.space.Model,
|
core.space.Model,
|
||||||
{
|
{
|
||||||
email: systemAccountEmail,
|
email: systemAccountEmail,
|
||||||
name: systemAccountEmail,
|
|
||||||
role: AccountRole.Owner
|
role: AccountRole.Owner
|
||||||
},
|
},
|
||||||
core.account.System
|
core.account.System
|
||||||
|
@ -48,6 +48,5 @@ export class TSpace extends TDoc implements Space {
|
|||||||
@UX(core.string.Account, undefined, undefined, 'name')
|
@UX(core.string.Account, undefined, undefined, 'name')
|
||||||
export class TAccount extends TDoc implements Account {
|
export class TAccount extends TDoc implements Account {
|
||||||
email!: string
|
email!: string
|
||||||
name!: string
|
|
||||||
role!: AccountRole
|
role!: AccountRole
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,6 @@ describe('memdb', () => {
|
|||||||
})
|
})
|
||||||
const account = await model.createDoc(core.class.Account, core.space.Model, {
|
const account = await model.createDoc(core.class.Account, core.space.Model, {
|
||||||
email: 'email',
|
email: 'email',
|
||||||
name: 'test',
|
|
||||||
role: 0
|
role: 0
|
||||||
})
|
})
|
||||||
await model.updateDoc(core.class.Space, core.space.Model, space, { $push: { members: account } })
|
await model.updateDoc(core.class.Space, core.space.Model, space, { $push: { members: account } })
|
||||||
|
@ -329,7 +329,6 @@ export interface Space extends Doc {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export interface Account extends Doc {
|
export interface Account extends Doc {
|
||||||
name: string
|
|
||||||
email: string
|
email: string
|
||||||
role: AccountRole
|
role: AccountRole
|
||||||
}
|
}
|
||||||
|
@ -194,8 +194,8 @@ export function genMinModel (): TxCUD<Doc>[] {
|
|||||||
const u1 = 'User1' as Ref<Account>
|
const u1 = 'User1' as Ref<Account>
|
||||||
const u2 = 'User2' as Ref<Account>
|
const u2 = 'User2' as Ref<Account>
|
||||||
txes.push(
|
txes.push(
|
||||||
createDoc(core.class.Account, { email: 'user1@site.com', name: 'user1', role: 0 }, u1),
|
createDoc(core.class.Account, { email: 'user1@site.com', role: 0 }, u1),
|
||||||
createDoc(core.class.Account, { email: 'user2@site.com', name: 'user2', role: 0 }, u2),
|
createDoc(core.class.Account, { email: 'user2@site.com', role: 0 }, u2),
|
||||||
createDoc(core.class.Space, {
|
createDoc(core.class.Space, {
|
||||||
name: 'Sp1',
|
name: 'Sp1',
|
||||||
description: '',
|
description: '',
|
||||||
|
@ -101,7 +101,6 @@ describe('query', () => {
|
|||||||
|
|
||||||
await factory.createDoc(core.class.Account, core.space.Model, {
|
await factory.createDoc(core.class.Account, core.space.Model, {
|
||||||
email: 'user1@site.com',
|
email: 'user1@site.com',
|
||||||
name: 'user1',
|
|
||||||
role: 0
|
role: 0
|
||||||
})
|
})
|
||||||
await factory.createDoc<Channel>(core.class.Space, core.space.Model, {
|
await factory.createDoc<Channel>(core.class.Space, core.space.Model, {
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
const activityQuery = newActivity(client, attrs)
|
const activityQuery = newActivity(client, attrs)
|
||||||
|
|
||||||
let viewlets: Map<ActivityKey, TxViewlet>
|
let viewlets: Map<ActivityKey, TxViewlet[]> = new Map()
|
||||||
|
|
||||||
let allViewlets: TxViewlet[] = []
|
let allViewlets: TxViewlet[] = []
|
||||||
let editableMap: Map<Ref<Class<Doc>>, boolean> | undefined = undefined
|
let editableMap: Map<Ref<Class<Doc>>, boolean> | undefined = undefined
|
||||||
@ -61,7 +61,18 @@
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
$: viewlets = new Map(allViewlets.map((r) => [activityKey(r.objectClass, r.txClass), r]))
|
$: viewlets = buildViewletsMap(allViewlets)
|
||||||
|
|
||||||
|
function buildViewletsMap (allViewlets: TxViewlet[]): Map<ActivityKey, TxViewlet[]> {
|
||||||
|
const viewlets = new Map()
|
||||||
|
for (const res of allViewlets) {
|
||||||
|
const key = activityKey(res.objectClass, res.txClass)
|
||||||
|
const arr = viewlets.get(key) ?? []
|
||||||
|
arr.push(res)
|
||||||
|
viewlets.set(key, arr)
|
||||||
|
}
|
||||||
|
return viewlets
|
||||||
|
}
|
||||||
|
|
||||||
let loading = false
|
let loading = false
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
import TxViewTx from './TxViewTx.svelte'
|
import TxViewTx from './TxViewTx.svelte'
|
||||||
|
|
||||||
export let tx: DisplayTx
|
export let tx: DisplayTx
|
||||||
export let viewlets: Map<ActivityKey, TxViewlet>
|
export let viewlets: Map<ActivityKey, TxViewlet[]>
|
||||||
export let showIcon: boolean = true
|
export let showIcon: boolean = true
|
||||||
export let isNew: boolean = false
|
export let isNew: boolean = false
|
||||||
export let isNextNew: boolean = false
|
export let isNextNew: boolean = false
|
||||||
|
@ -5,6 +5,7 @@ import core, {
|
|||||||
Client,
|
Client,
|
||||||
Collection,
|
Collection,
|
||||||
Doc,
|
Doc,
|
||||||
|
Hierarchy,
|
||||||
Obj,
|
Obj,
|
||||||
Ref,
|
Ref,
|
||||||
TxCUD,
|
TxCUD,
|
||||||
@ -14,7 +15,8 @@ import core, {
|
|||||||
TxOperations,
|
TxOperations,
|
||||||
TxProcessor,
|
TxProcessor,
|
||||||
TxUpdateDoc,
|
TxUpdateDoc,
|
||||||
getObjectValue
|
getObjectValue,
|
||||||
|
matchQuery
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import { Asset, IntlString, getResource, translate } from '@hcengineering/platform'
|
import { Asset, IntlString, getResource, translate } from '@hcengineering/platform'
|
||||||
import { getAttributePresenterClass } from '@hcengineering/presentation'
|
import { getAttributePresenterClass } from '@hcengineering/presentation'
|
||||||
@ -82,7 +84,11 @@ export function getDTxProps (dtx: DisplayTx): any {
|
|||||||
return { tx: dtx.tx, value: dtx.doc, isOwnTx: dtx.isOwnTx, prevValue: dtx.prevDoc }
|
return { tx: dtx.tx, value: dtx.doc, isOwnTx: dtx.isOwnTx, prevValue: dtx.prevDoc }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getViewlet (viewlets: Map<ActivityKey, TxViewlet>, dtx: DisplayTx): TxDisplayViewlet | undefined {
|
function getViewlet (
|
||||||
|
viewlets: Map<ActivityKey, TxViewlet[]>,
|
||||||
|
dtx: DisplayTx,
|
||||||
|
hierarchy: Hierarchy
|
||||||
|
): TxDisplayViewlet | undefined {
|
||||||
let key: string
|
let key: string
|
||||||
if (dtx.mixinTx?.mixin !== undefined && dtx.tx._id === dtx.mixinTx._id) {
|
if (dtx.mixinTx?.mixin !== undefined && dtx.tx._id === dtx.mixinTx._id) {
|
||||||
key = activityKey(dtx.mixinTx.mixin, dtx.tx._class)
|
key = activityKey(dtx.mixinTx.mixin, dtx.tx._class)
|
||||||
@ -91,13 +97,21 @@ function getViewlet (viewlets: Map<ActivityKey, TxViewlet>, dtx: DisplayTx): TxD
|
|||||||
}
|
}
|
||||||
const vl = viewlets.get(key)
|
const vl = viewlets.get(key)
|
||||||
if (vl !== undefined) {
|
if (vl !== undefined) {
|
||||||
return { ...vl, pseudo: false }
|
for (const viewlet of vl) {
|
||||||
|
if (viewlet.match === undefined) {
|
||||||
|
return { ...viewlet, pseudo: false }
|
||||||
|
}
|
||||||
|
const res = matchQuery([dtx.tx], viewlet.match, dtx.tx._class, hierarchy)
|
||||||
|
if (res.length > 0) {
|
||||||
|
return { ...viewlet, pseudo: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateViewlet (
|
export async function updateViewlet (
|
||||||
client: TxOperations,
|
client: TxOperations,
|
||||||
viewlets: Map<ActivityKey, TxViewlet>,
|
viewlets: Map<ActivityKey, TxViewlet[]>,
|
||||||
dtx: DisplayTx
|
dtx: DisplayTx
|
||||||
): Promise<{
|
): Promise<{
|
||||||
viewlet: TxDisplayViewlet
|
viewlet: TxDisplayViewlet
|
||||||
@ -107,7 +121,7 @@ export async function updateViewlet (
|
|||||||
modelIcon: Asset | undefined
|
modelIcon: Asset | undefined
|
||||||
iconComponent: AnyComponent | undefined
|
iconComponent: AnyComponent | undefined
|
||||||
}> {
|
}> {
|
||||||
let viewlet = getViewlet(viewlets, dtx)
|
let viewlet = getViewlet(viewlets, dtx, client.getHierarchy())
|
||||||
|
|
||||||
const props = getDTxProps(dtx)
|
const props = getDTxProps(dtx)
|
||||||
let model: AttributeModel[] = []
|
let model: AttributeModel[] = []
|
||||||
|
@ -946,7 +946,6 @@ async function synchronizeUsers (
|
|||||||
})
|
})
|
||||||
accountId = await ops.client.createDoc(contact.class.PersonAccount, core.space.Model, {
|
accountId = await ops.client.createDoc(contact.class.PersonAccount, core.space.Model, {
|
||||||
email: u.EMAIL,
|
email: u.EMAIL,
|
||||||
name: combineName(u.NAME, u.LAST_NAME),
|
|
||||||
person: employeeId,
|
person: employeeId,
|
||||||
role: AccountRole.User
|
role: AccountRole.User
|
||||||
})
|
})
|
||||||
|
@ -83,7 +83,6 @@
|
|||||||
"MergePersons": "Merge contacts",
|
"MergePersons": "Merge contacts",
|
||||||
"MergePersonsFrom": "Source contact",
|
"MergePersonsFrom": "Source contact",
|
||||||
"MergePersonsTo": "Final contact",
|
"MergePersonsTo": "Final contact",
|
||||||
"DisplayName": "Display name",
|
|
||||||
"SelectAvatar": "Select avatar",
|
"SelectAvatar": "Select avatar",
|
||||||
"AvatarProvider": "Avatar provider",
|
"AvatarProvider": "Avatar provider",
|
||||||
"GravatarsManaged": "Gravatars are managed",
|
"GravatarsManaged": "Gravatars are managed",
|
||||||
|
@ -84,7 +84,6 @@
|
|||||||
"MergePersons": "Объеденить контакта",
|
"MergePersons": "Объеденить контакта",
|
||||||
"MergePersonsFrom": "Исходный контакт",
|
"MergePersonsFrom": "Исходный контакт",
|
||||||
"MergePersonsTo": "Финальный контакт",
|
"MergePersonsTo": "Финальный контакт",
|
||||||
"DisplayName": "Отображаемое имя",
|
|
||||||
"SelectAvatar": "Выбрать аватар",
|
"SelectAvatar": "Выбрать аватар",
|
||||||
"GravatarsManaged": "Граватары управляются",
|
"GravatarsManaged": "Граватары управляются",
|
||||||
"Through": "через",
|
"Through": "через",
|
||||||
|
@ -62,7 +62,6 @@
|
|||||||
|
|
||||||
await client.createDoc(contact.class.PersonAccount, core.space.Model, {
|
await client.createDoc(contact.class.PersonAccount, core.space.Model, {
|
||||||
email: email.trim(),
|
email: email.trim(),
|
||||||
name,
|
|
||||||
person: id,
|
person: id,
|
||||||
role: AccountRole.User
|
role: AccountRole.User
|
||||||
})
|
})
|
||||||
|
@ -14,13 +14,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Channel, Employee, PersonAccount, getFirstName, getLastName, Person } from '@hcengineering/contact'
|
import {
|
||||||
import { AccountRole, getCurrentAccount, Ref } from '@hcengineering/core'
|
Channel,
|
||||||
import login from '@hcengineering/login'
|
Employee,
|
||||||
import { getResource } from '@hcengineering/platform'
|
Person,
|
||||||
|
PersonAccount,
|
||||||
|
combineName,
|
||||||
|
getFirstName,
|
||||||
|
getLastName
|
||||||
|
} from '@hcengineering/contact'
|
||||||
|
import { AccountRole, Ref, getCurrentAccount } from '@hcengineering/core'
|
||||||
import { AttributeEditor, createQuery, getClient } from '@hcengineering/presentation'
|
import { AttributeEditor, createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import setting, { IntegrationType } from '@hcengineering/setting'
|
import setting, { IntegrationType } from '@hcengineering/setting'
|
||||||
import { createFocusManager, EditBox, FocusHandler, Scroller } from '@hcengineering/ui'
|
import { EditBox, FocusHandler, Scroller, createFocusManager } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import { ChannelsDropdown } from '..'
|
import { ChannelsDropdown } from '..'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
@ -61,13 +67,15 @@
|
|||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
async function firstNameChange () {
|
async function firstNameChange () {
|
||||||
const changeName = await getResource(login.function.ChangeName)
|
await client.update(object, {
|
||||||
await changeName(firstName, getLastName(object.name))
|
name: combineName(firstName, getLastName(object.name))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function lastNameChange () {
|
async function lastNameChange () {
|
||||||
const changeName = await getResource(login.function.ChangeName)
|
await client.update(object, {
|
||||||
await changeName(getFirstName(object.name), lastName)
|
name: combineName(getFirstName(object.name), lastName)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let integrations: Set<Ref<IntegrationType>> = new Set<Ref<IntegrationType>>()
|
let integrations: Set<Ref<IntegrationType>> = new Set<Ref<IntegrationType>>()
|
||||||
@ -76,7 +84,7 @@
|
|||||||
integrations = new Set(res.map((p) => p.type))
|
integrations = new Set(res.map((p) => p.type))
|
||||||
})
|
})
|
||||||
|
|
||||||
const sendOpen = () => dispatch('open', { ignoreKeys: ['comments', 'name', 'channels', 'city', 'displayName'] })
|
const sendOpen = () => dispatch('open', { ignoreKeys: ['comments', 'name', 'channels', 'city'] })
|
||||||
onMount(sendOpen)
|
onMount(sendOpen)
|
||||||
|
|
||||||
async function onAvatarDone () {
|
async function onAvatarDone () {
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2023 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License. You may
|
||||||
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
//
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
-->
|
||||||
|
<script lang="ts">
|
||||||
|
import { Person, formatName } from '@hcengineering/contact'
|
||||||
|
import { TxUpdateDoc } from '@hcengineering/core'
|
||||||
|
import contact from '../../plugin'
|
||||||
|
import { Label } from '@hcengineering/ui'
|
||||||
|
import activity from '@hcengineering/activity'
|
||||||
|
|
||||||
|
export let tx: TxUpdateDoc<Person>
|
||||||
|
|
||||||
|
const val = tx.operations.name
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if val}
|
||||||
|
<span class="lower"><Label label={activity.string.Changed} /></span>
|
||||||
|
<span class="lower"><Label label={contact.string.Name} /></span>
|
||||||
|
<span class="lower"><Label label={activity.string.To} /></span>
|
||||||
|
<span class="strong overflow-label">
|
||||||
|
{formatName(val)}
|
||||||
|
</span>
|
||||||
|
{/if}
|
@ -88,6 +88,7 @@ import ActivityChannelMessage from './components/activity/ActivityChannelMessage
|
|||||||
import ActivityChannelPresenter from './components/activity/ActivityChannelPresenter.svelte'
|
import ActivityChannelPresenter from './components/activity/ActivityChannelPresenter.svelte'
|
||||||
import ExpandRightDouble from './components/icons/ExpandRightDouble.svelte'
|
import ExpandRightDouble from './components/icons/ExpandRightDouble.svelte'
|
||||||
import IconMembers from './components/icons/Members.svelte'
|
import IconMembers from './components/icons/Members.svelte'
|
||||||
|
import TxNameChange from './components/activity/TxNameChange.svelte'
|
||||||
|
|
||||||
import contact from './plugin'
|
import contact from './plugin'
|
||||||
import {
|
import {
|
||||||
@ -274,6 +275,9 @@ export default async (): Promise<Resources> => ({
|
|||||||
KickEmployee: kickEmployee,
|
KickEmployee: kickEmployee,
|
||||||
OpenChannel: openChannelURL
|
OpenChannel: openChannelURL
|
||||||
},
|
},
|
||||||
|
activity: {
|
||||||
|
TxNameChange
|
||||||
|
},
|
||||||
component: {
|
component: {
|
||||||
ContactArrayEditor,
|
ContactArrayEditor,
|
||||||
PersonEditor,
|
PersonEditor,
|
||||||
|
@ -140,7 +140,9 @@ export async function getRefs (
|
|||||||
|
|
||||||
export async function getCurrentEmployeeName (): Promise<string> {
|
export async function getCurrentEmployeeName (): Promise<string> {
|
||||||
const me = getCurrentAccount() as PersonAccount
|
const me = getCurrentAccount() as PersonAccount
|
||||||
return formatName(me.name)
|
const client = getClient()
|
||||||
|
const employee = await client.findOne(contact.class.Person, { _id: me.person })
|
||||||
|
return employee !== undefined ? formatName(employee.name) : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCurrentEmployeeEmail (): Promise<string> {
|
export async function getCurrentEmployeeEmail (): Promise<string> {
|
||||||
|
@ -139,7 +139,6 @@ export interface Status extends AttachedDoc {
|
|||||||
export interface Employee extends Person {
|
export interface Employee extends Person {
|
||||||
active: boolean
|
active: boolean
|
||||||
statuses?: number
|
statuses?: number
|
||||||
displayName?: string | null
|
|
||||||
position?: string | null
|
position?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +262,6 @@ export const contactPlugin = plugin(contactId, {
|
|||||||
UseColor: '' as IntlString,
|
UseColor: '' as IntlString,
|
||||||
PersonFirstNamePlaceholder: '' as IntlString,
|
PersonFirstNamePlaceholder: '' as IntlString,
|
||||||
PersonLastNamePlaceholder: '' as IntlString,
|
PersonLastNamePlaceholder: '' as IntlString,
|
||||||
DisplayName: '' as IntlString,
|
|
||||||
NumberMembers: '' as IntlString,
|
NumberMembers: '' as IntlString,
|
||||||
Position: '' as IntlString
|
Position: '' as IntlString
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
import { AttachedData, Class, Client, Doc, FindResult, Ref, Hierarchy } from '@hcengineering/core'
|
import { AttachedData, Class, Client, Doc, FindResult, Ref, Hierarchy } from '@hcengineering/core'
|
||||||
import { IconSize } from '@hcengineering/ui'
|
import { IconSize } from '@hcengineering/ui'
|
||||||
import { MD5 } from 'crypto-js'
|
import { MD5 } from 'crypto-js'
|
||||||
import { Channel, Contact, contactPlugin, Employee, Person } from '.'
|
import { Channel, Contact, contactPlugin, Person } from '.'
|
||||||
import { AVATAR_COLORS, GravatarPlaceholderType } from './types'
|
import { AVATAR_COLORS, GravatarPlaceholderType } from './types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,19 +212,12 @@ export function formatName (name: string): string {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export function getName (hierarchy: Hierarchy, value: Contact): string {
|
export function getName (hierarchy: Hierarchy, value: Contact): string {
|
||||||
if (isEmployee(hierarchy, value)) {
|
if (isPerson(hierarchy, value)) {
|
||||||
return hierarchy.as(value, contactPlugin.mixin.Employee).displayName ?? formatName(value.name)
|
|
||||||
}
|
|
||||||
if (isPerson(value)) {
|
|
||||||
return formatName(value.name)
|
return formatName(value.name)
|
||||||
}
|
}
|
||||||
return value.name
|
return value.name
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmployee (hierarchy: Hierarchy, value: Contact): value is Employee {
|
function isPerson (hierarchy: Hierarchy, value: Contact): value is Person {
|
||||||
return hierarchy.hasMixin(value, contactPlugin.mixin.Employee)
|
return hierarchy.isDerived(value._class, contactPlugin.class.Person)
|
||||||
}
|
|
||||||
|
|
||||||
function isPerson (value: Contact): value is Person {
|
|
||||||
return value._class === contactPlugin.class.Person
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
|
|
||||||
const fields = [
|
const fields = [
|
||||||
|
{ id: 'given-name', name: 'first', i18n: login.string.FirstName, short: true },
|
||||||
|
{ id: 'family-name', name: 'last', i18n: login.string.LastName, short: true },
|
||||||
{
|
{
|
||||||
name: 'workspace',
|
name: 'workspace',
|
||||||
i18n: login.string.Workspace,
|
i18n: login.string.Workspace,
|
||||||
@ -34,7 +36,9 @@
|
|||||||
]
|
]
|
||||||
|
|
||||||
const object = {
|
const object = {
|
||||||
workspace: ''
|
workspace: '',
|
||||||
|
first: '',
|
||||||
|
last: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
let status: Status<any> = OK
|
let status: Status<any> = OK
|
||||||
@ -54,7 +58,7 @@
|
|||||||
func: async () => {
|
func: async () => {
|
||||||
status = new Status(Severity.INFO, login.status.ConnectingToServer, {})
|
status = new Status(Severity.INFO, login.status.ConnectingToServer, {})
|
||||||
|
|
||||||
const [loginStatus, result] = await createWorkspace(object.workspace)
|
const [loginStatus, result] = await createWorkspace(object.workspace, object.first, object.last)
|
||||||
status = loginStatus
|
status = loginStatus
|
||||||
|
|
||||||
if (result !== undefined) {
|
if (result !== undefined) {
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
$: fields =
|
$: fields =
|
||||||
page === 'login'
|
page === 'login'
|
||||||
? [
|
? [
|
||||||
|
{ id: 'given-name', name: 'first', i18n: login.string.FirstName, short: true },
|
||||||
|
{ id: 'family-name', name: 'last', i18n: login.string.LastName, short: true },
|
||||||
{ id: 'email', name: 'username', i18n: login.string.Email },
|
{ id: 'email', name: 'username', i18n: login.string.Email },
|
||||||
{
|
{
|
||||||
id: 'current-password',
|
id: 'current-password',
|
||||||
@ -63,7 +65,7 @@
|
|||||||
|
|
||||||
const [loginStatus, result] =
|
const [loginStatus, result] =
|
||||||
page === 'login'
|
page === 'login'
|
||||||
? await join(object.username, object.password, location.query?.inviteId ?? '')
|
? await join(object.username, object.password, object.first, object.last, location.query?.inviteId ?? '')
|
||||||
: await signUpJoin(
|
: await signUpJoin(
|
||||||
object.username,
|
object.username,
|
||||||
object.password,
|
object.password,
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
import Form from './Form.svelte'
|
import Form from './Form.svelte'
|
||||||
|
|
||||||
const fields = [
|
const fields = [
|
||||||
{ id: 'given-name', name: 'first', i18n: login.string.FirstName, short: true },
|
|
||||||
{ id: 'family-name', name: 'last', i18n: login.string.LastName, short: true },
|
|
||||||
{ id: 'email', name: 'username', i18n: login.string.Email },
|
{ id: 'email', name: 'username', i18n: login.string.Email },
|
||||||
{ id: 'new-password', name: 'password', i18n: login.string.Password, password: true },
|
{ id: 'new-password', name: 'password', i18n: login.string.Password, password: true },
|
||||||
{ id: 'new-password', name: 'password2', i18n: login.string.PasswordRepeat, password: true }
|
{ id: 'new-password', name: 'password2', i18n: login.string.PasswordRepeat, password: true }
|
||||||
@ -44,7 +42,7 @@
|
|||||||
func: async () => {
|
func: async () => {
|
||||||
status = new Status(Severity.INFO, login.status.ConnectingToServer, {})
|
status = new Status(Severity.INFO, login.status.ConnectingToServer, {})
|
||||||
|
|
||||||
const [loginStatus, result] = await signUp(object.username, object.password, object.first, object.last)
|
const [loginStatus, result] = await signUp(object.username, object.password)
|
||||||
|
|
||||||
status = loginStatus
|
status = loginStatus
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import InviteLink from './components/InviteLink.svelte'
|
import InviteLink from './components/InviteLink.svelte'
|
||||||
import LoginApp from './components/LoginApp.svelte'
|
import LoginApp from './components/LoginApp.svelte'
|
||||||
import { changeName, changePassword, getWorkspaces, leaveWorkspace, selectWorkspace, sendInvite } from './utils'
|
import { changePassword, getWorkspaces, leaveWorkspace, selectWorkspace, sendInvite } from './utils'
|
||||||
/*!
|
/*!
|
||||||
* Anticrm Platform™ Login Plugin
|
* Anticrm Platform™ Login Plugin
|
||||||
* © 2020, 2021 Anticrm Platform Contributors.
|
* © 2020, 2021 Anticrm Platform Contributors.
|
||||||
@ -30,7 +30,6 @@ export default async () => ({
|
|||||||
InviteLink
|
InviteLink
|
||||||
},
|
},
|
||||||
function: {
|
function: {
|
||||||
ChangeName: changeName,
|
|
||||||
LeaveWorkspace: leaveWorkspace,
|
LeaveWorkspace: leaveWorkspace,
|
||||||
ChangePassword: changePassword,
|
ChangePassword: changePassword,
|
||||||
SelectWorkspace: selectWorkspace,
|
SelectWorkspace: selectWorkspace,
|
||||||
|
@ -76,12 +76,7 @@ export async function doLogin (email: string, password: string): Promise<[Status
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function signUp (
|
export async function signUp (email: string, password: string): Promise<[Status, LoginInfo | undefined]> {
|
||||||
email: string,
|
|
||||||
password: string,
|
|
||||||
first: string,
|
|
||||||
last: string
|
|
||||||
): Promise<[Status, LoginInfo | undefined]> {
|
|
||||||
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
||||||
|
|
||||||
if (accountsUrl === undefined) {
|
if (accountsUrl === undefined) {
|
||||||
@ -98,7 +93,7 @@ export async function signUp (
|
|||||||
|
|
||||||
const request = {
|
const request = {
|
||||||
method: 'createAccount',
|
method: 'createAccount',
|
||||||
params: [email, password, first, last]
|
params: [email, password]
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -116,7 +111,11 @@ export async function signUp (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createWorkspace (workspace: string): Promise<[Status, LoginInfo | undefined]> {
|
export async function createWorkspace (
|
||||||
|
workspace: string,
|
||||||
|
firstName: string,
|
||||||
|
lastName: string
|
||||||
|
): Promise<[Status, LoginInfo | undefined]> {
|
||||||
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
||||||
|
|
||||||
if (accountsUrl === undefined) {
|
if (accountsUrl === undefined) {
|
||||||
@ -143,7 +142,7 @@ export async function createWorkspace (workspace: string): Promise<[Status, Logi
|
|||||||
|
|
||||||
const request = {
|
const request = {
|
||||||
method: 'createWorkspace',
|
method: 'createWorkspace',
|
||||||
params: [workspace]
|
params: [workspace, firstName, lastName]
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -426,6 +425,8 @@ export async function getInviteLink (expHours: number = 1, emailMask: string = '
|
|||||||
export async function join (
|
export async function join (
|
||||||
email: string,
|
email: string,
|
||||||
password: string,
|
password: string,
|
||||||
|
first: string,
|
||||||
|
last: string,
|
||||||
inviteId: string
|
inviteId: string
|
||||||
): Promise<[Status, WorkspaceLoginInfo | undefined]> {
|
): Promise<[Status, WorkspaceLoginInfo | undefined]> {
|
||||||
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
||||||
@ -444,7 +445,7 @@ export async function join (
|
|||||||
|
|
||||||
const request = {
|
const request = {
|
||||||
method: 'join',
|
method: 'join',
|
||||||
params: [email, password, inviteId]
|
params: [email, password, first, last, inviteId]
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -503,37 +504,6 @@ export async function signUpJoin (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function changeName (first: string, last: string): Promise<void> {
|
|
||||||
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
|
||||||
|
|
||||||
if (accountsUrl === undefined) {
|
|
||||||
throw new Error('accounts url not specified')
|
|
||||||
}
|
|
||||||
|
|
||||||
const overrideToken = getMetadata(login.metadata.OverrideLoginToken)
|
|
||||||
if (overrideToken !== undefined) {
|
|
||||||
const endpoint = getMetadata(login.metadata.OverrideEndpoint)
|
|
||||||
if (endpoint !== undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const token = getMetadata(presentation.metadata.Token) as string
|
|
||||||
|
|
||||||
const request = {
|
|
||||||
method: 'changeName',
|
|
||||||
params: [first, last]
|
|
||||||
}
|
|
||||||
|
|
||||||
await fetch(accountsUrl, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
Authorization: 'Bearer ' + token,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(request)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function changePassword (oldPassword: string, password: string): Promise<void> {
|
export async function changePassword (oldPassword: string, password: string): Promise<void> {
|
||||||
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
const accountsUrl = getMetadata(login.metadata.AccountsUrl)
|
||||||
|
|
||||||
|
@ -69,7 +69,6 @@ export default plugin(loginId, {
|
|||||||
InviteLimit: '' as IntlString
|
InviteLimit: '' as IntlString
|
||||||
},
|
},
|
||||||
function: {
|
function: {
|
||||||
ChangeName: '' as Resource<(first: string, last: string) => Promise<void>>,
|
|
||||||
SendInvite: '' as Resource<(email: string) => Promise<void>>,
|
SendInvite: '' as Resource<(email: string) => Promise<void>>,
|
||||||
LeaveWorkspace: '' as Resource<(email: string) => Promise<void>>,
|
LeaveWorkspace: '' as Resource<(email: string) => Promise<void>>,
|
||||||
ChangePassword: '' as Resource<(oldPassword: string, password: string) => Promise<void>>,
|
ChangePassword: '' as Resource<(oldPassword: string, password: string) => Promise<void>>,
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewlets: Map<ActivityKey, TxViewlet>
|
let viewlets: Map<ActivityKey, TxViewlet[]>
|
||||||
|
|
||||||
const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
|
const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => {
|
||||||
if (dir === 'vertical') {
|
if (dir === 'vertical') {
|
||||||
@ -121,7 +121,14 @@
|
|||||||
|
|
||||||
const descriptors = createQuery()
|
const descriptors = createQuery()
|
||||||
descriptors.query(activity.class.TxViewlet, {}, (result) => {
|
descriptors.query(activity.class.TxViewlet, {}, (result) => {
|
||||||
viewlets = new Map(result.map((r) => [activityKey(r.objectClass, r.txClass), r]))
|
viewlets = new Map()
|
||||||
|
for (const res of result) {
|
||||||
|
const key = activityKey(res.objectClass, res.txClass)
|
||||||
|
const arr = viewlets.get(key) ?? []
|
||||||
|
arr.push(res)
|
||||||
|
viewlets.set(key, arr)
|
||||||
|
}
|
||||||
|
viewlets = viewlets
|
||||||
})
|
})
|
||||||
|
|
||||||
let selected = 0
|
let selected = 0
|
||||||
|
@ -105,11 +105,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewlets: Map<ActivityKey, TxViewlet>
|
let viewlets: Map<ActivityKey, TxViewlet[]>
|
||||||
|
|
||||||
const descriptors = createQuery()
|
const descriptors = createQuery()
|
||||||
descriptors.query(activity.class.TxViewlet, {}, (result) => {
|
descriptors.query(activity.class.TxViewlet, {}, (result) => {
|
||||||
viewlets = new Map(result.map((r) => [activityKey(r.objectClass, r.txClass), r]))
|
viewlets = new Map()
|
||||||
|
for (const res of result) {
|
||||||
|
const key = activityKey(res.objectClass, res.txClass)
|
||||||
|
const arr = viewlets.get(key) ?? []
|
||||||
|
arr.push(res)
|
||||||
|
viewlets.set(key, arr)
|
||||||
|
}
|
||||||
|
viewlets = viewlets
|
||||||
})
|
})
|
||||||
|
|
||||||
let selected = 0
|
let selected = 0
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
import TxView from './TxView.svelte'
|
import TxView from './TxView.svelte'
|
||||||
|
|
||||||
export let value: DocUpdates
|
export let value: DocUpdates
|
||||||
export let viewlets: Map<ActivityKey, TxViewlet>
|
export let viewlets: Map<ActivityKey, TxViewlet[]>
|
||||||
export let selected: boolean
|
export let selected: boolean
|
||||||
export let preview: boolean = false
|
export let preview: boolean = false
|
||||||
|
|
||||||
|
@ -125,11 +125,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewlets: Map<ActivityKey, TxViewlet>
|
let viewlets: Map<ActivityKey, TxViewlet[]>
|
||||||
|
|
||||||
const descriptors = createQuery()
|
const descriptors = createQuery()
|
||||||
descriptors.query(activity.class.TxViewlet, {}, (result) => {
|
descriptors.query(activity.class.TxViewlet, {}, (result) => {
|
||||||
viewlets = new Map(result.map((r) => [activityKey(r.objectClass, r.txClass), r]))
|
viewlets = new Map()
|
||||||
|
for (const res of result) {
|
||||||
|
const key = activityKey(res.objectClass, res.txClass)
|
||||||
|
const arr = viewlets.get(key) ?? []
|
||||||
|
arr.push(res)
|
||||||
|
viewlets.set(key, arr)
|
||||||
|
}
|
||||||
|
viewlets = viewlets
|
||||||
})
|
})
|
||||||
|
|
||||||
let selected = 0
|
let selected = 0
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
export let value: PersonAccount
|
export let value: PersonAccount
|
||||||
export let items: DocUpdates[]
|
export let items: DocUpdates[]
|
||||||
export let viewlets: Map<ActivityKey, TxViewlet>
|
export let viewlets: Map<ActivityKey, TxViewlet[]>
|
||||||
export let selected: boolean
|
export let selected: boolean
|
||||||
|
|
||||||
$: firstItem = items[0]
|
$: firstItem = items[0]
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
export let tx: TxCUD<Doc>
|
export let tx: TxCUD<Doc>
|
||||||
export let objectId: Ref<Doc>
|
export let objectId: Ref<Doc>
|
||||||
export let viewlets: Map<ActivityKey, TxViewlet>
|
export let viewlets: Map<ActivityKey, TxViewlet[]>
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
let ptx: DisplayTx | undefined
|
let ptx: DisplayTx | undefined
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
import request from '../plugin'
|
import request from '../plugin'
|
||||||
|
|
||||||
export let tx: Tx
|
export let tx: Tx
|
||||||
const viewlets: Map<ActivityKey, TxViewlet> = new Map<ActivityKey, TxViewlet>()
|
const viewlets: Map<ActivityKey, TxViewlet[]> = new Map<ActivityKey, TxViewlet[]>()
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
let ptx: DisplayTx | undefined
|
let ptx: DisplayTx | undefined
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { PersonAccount, formatName } from '@hcengineering/contact'
|
import contact, { PersonAccount } from '@hcengineering/contact'
|
||||||
import { EmployeePresenter, personByIdStore } from '@hcengineering/contact-resources'
|
import { EmployeePresenter, personByIdStore } from '@hcengineering/contact-resources'
|
||||||
import { AccountRole, getCurrentAccount, SortingOrder } from '@hcengineering/core'
|
import { AccountRole, SortingOrder, getCurrentAccount } from '@hcengineering/core'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { DropdownIntlItem, DropdownLabelsIntl, Icon, Label, EditBox } from '@hcengineering/ui'
|
import { DropdownIntlItem, DropdownLabelsIntl, EditBox, Icon, Label } from '@hcengineering/ui'
|
||||||
import setting from '../plugin'
|
import setting from '../plugin'
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
@ -64,13 +64,13 @@
|
|||||||
<div class="ac-column max">
|
<div class="ac-column max">
|
||||||
{#each accounts as account (account._id)}
|
{#each accounts as account (account._id)}
|
||||||
{@const employee = $personByIdStore.get(account.person)}
|
{@const employee = $personByIdStore.get(account.person)}
|
||||||
{#if account.name.includes(search)}
|
{#if employee?.name?.includes(search)}
|
||||||
<div class="flex-row-center p-2">
|
<div class="flex-row-center p-2">
|
||||||
<div class="p-1 min-w-80">
|
<div class="p-1 min-w-80">
|
||||||
{#if employee}
|
{#if employee}
|
||||||
<EmployeePresenter value={employee} disabled={false} />
|
<EmployeePresenter value={employee} disabled={false} />
|
||||||
{:else}
|
{:else}
|
||||||
{formatName(account.name)}
|
{account.email}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<DropdownLabelsIntl
|
<DropdownLabelsIntl
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee, PersonAccount, getFirstName, getLastName } from '@hcengineering/contact'
|
import contact, { Employee, PersonAccount, combineName, getFirstName, getLastName } from '@hcengineering/contact'
|
||||||
import { ChannelsEditor, EditableAvatar, employeeByIdStore } from '@hcengineering/contact-resources'
|
import { ChannelsEditor, EditableAvatar, employeeByIdStore } from '@hcengineering/contact-resources'
|
||||||
import { Ref, getCurrentAccount } from '@hcengineering/core'
|
import { Ref, getCurrentAccount } from '@hcengineering/core'
|
||||||
import login from '@hcengineering/login'
|
import login from '@hcengineering/login'
|
||||||
@ -30,7 +30,6 @@
|
|||||||
const employee = account !== undefined ? $employeeByIdStore.get(account.person as Ref<Employee>) : undefined
|
const employee = account !== undefined ? $employeeByIdStore.get(account.person as Ref<Employee>) : undefined
|
||||||
let firstName = employee ? getFirstName(employee.name) : ''
|
let firstName = employee ? getFirstName(employee.name) : ''
|
||||||
let lastName = employee ? getLastName(employee.name) : ''
|
let lastName = employee ? getLastName(employee.name) : ''
|
||||||
let displayName = employee?.displayName ?? ''
|
|
||||||
|
|
||||||
onDestroy(
|
onDestroy(
|
||||||
employeeByIdStore.subscribe((p) => {
|
employeeByIdStore.subscribe((p) => {
|
||||||
@ -38,7 +37,6 @@
|
|||||||
if (emp) {
|
if (emp) {
|
||||||
firstName = getFirstName(emp.name)
|
firstName = getFirstName(emp.name)
|
||||||
lastName = getLastName(emp.name)
|
lastName = getLastName(emp.name)
|
||||||
displayName = emp?.displayName ?? ''
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -74,10 +72,10 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeDisplayName () {
|
async function nameChange () {
|
||||||
if (employee) {
|
if (employee) {
|
||||||
client.update(employee, {
|
await client.update(employee, {
|
||||||
displayName: displayName.trim() === '' ? null : displayName
|
name: combineName(firstName, lastName)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,27 +108,14 @@
|
|||||||
kind={'large-style'}
|
kind={'large-style'}
|
||||||
autoFocus
|
autoFocus
|
||||||
focusIndex={1}
|
focusIndex={1}
|
||||||
on:change={async () => {
|
on:change={nameChange}
|
||||||
const changeName = await getResource(login.function.ChangeName)
|
|
||||||
changeName(firstName, lastName)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<EditBox
|
<EditBox
|
||||||
placeholder={contact.string.PersonLastNamePlaceholder}
|
placeholder={contact.string.PersonLastNamePlaceholder}
|
||||||
bind:value={lastName}
|
bind:value={lastName}
|
||||||
kind={'large-style'}
|
kind={'large-style'}
|
||||||
focusIndex={2}
|
focusIndex={2}
|
||||||
on:change={async () => {
|
on:change={nameChange}
|
||||||
const changeName = await getResource(login.function.ChangeName)
|
|
||||||
changeName(firstName, lastName)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<EditBox
|
|
||||||
placeholder={contact.string.DisplayName}
|
|
||||||
bind:value={displayName}
|
|
||||||
kind={'large-style'}
|
|
||||||
focusIndex={2}
|
|
||||||
on:change={changeDisplayName}
|
|
||||||
/>
|
/>
|
||||||
<div class="location">
|
<div class="location">
|
||||||
<AttributeEditor
|
<AttributeEditor
|
||||||
|
@ -184,7 +184,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<div class="ml-2 flex-col">
|
<div class="ml-2 flex-col">
|
||||||
{#if account}
|
{#if account}
|
||||||
<div class="overflow-label fs-bold caption-color">{formatName(account.name)}</div>
|
<div class="overflow-label fs-bold caption-color">
|
||||||
|
{employee !== undefined ? formatName(employee.name) : ''}
|
||||||
|
</div>
|
||||||
<div class="overflow-label text-sm content-dark-color">{account.email}</div>
|
<div class="overflow-label text-sm content-dark-color">{account.email}</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -253,7 +253,9 @@ async function getEmailNotification (
|
|||||||
attachedTo: { $in: Array.from(contacts) }
|
attachedTo: { $in: Array.from(contacts) }
|
||||||
})
|
})
|
||||||
|
|
||||||
const senderName = formatName(sender.name)
|
const senderPerson = (await control.findAll(contact.class.Person, { _id: sender.person }))[0]
|
||||||
|
|
||||||
|
const senderName = senderPerson !== undefined ? formatName(senderPerson.name) : ''
|
||||||
const content = await getContent(doc, senderName, type, control, '')
|
const content = await getContent(doc, senderName, type, control, '')
|
||||||
if (content === undefined) return []
|
if (content === undefined) return []
|
||||||
|
|
||||||
|
@ -221,8 +221,12 @@ async function createEmailNotificationTxes (
|
|||||||
|
|
||||||
const receiver = (await control.modelDb.findAll(contact.class.PersonAccount, { _id: receiverId }))[0]
|
const receiver = (await control.modelDb.findAll(contact.class.PersonAccount, { _id: receiverId }))[0]
|
||||||
if (receiver === undefined) return
|
if (receiver === undefined) return
|
||||||
|
let senderName = ''
|
||||||
|
|
||||||
const senderName = sender !== undefined ? formatName(sender.name) : ''
|
if (sender !== undefined) {
|
||||||
|
const senderPerson = (await control.modelDb.findAll(contact.class.Person, { _id: sender.person }))[0]
|
||||||
|
senderName = senderPerson !== undefined ? formatName(senderPerson.name) : ''
|
||||||
|
}
|
||||||
|
|
||||||
const content = await getContent(doc, senderName, type, control, data)
|
const content = await getContent(doc, senderName, type, control, data)
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ describe('server', () => {
|
|||||||
})
|
})
|
||||||
await methods.assignWorkspace(db, '', {
|
await methods.assignWorkspace(db, '', {
|
||||||
method: 'assignWorkspace',
|
method: 'assignWorkspace',
|
||||||
params: ['andrey', workspace]
|
params: ['andrey', workspace, 'firstName', 'lastName']
|
||||||
})
|
})
|
||||||
|
|
||||||
const request: any = {
|
const request: any = {
|
||||||
@ -140,7 +140,7 @@ describe('server', () => {
|
|||||||
})
|
})
|
||||||
await methods.assignWorkspace(db, '', {
|
await methods.assignWorkspace(db, '', {
|
||||||
method: 'assignWorkspace',
|
method: 'assignWorkspace',
|
||||||
params: ['andrey', workspace]
|
params: ['andrey', workspace, 'first', 'last']
|
||||||
})
|
})
|
||||||
|
|
||||||
// Check we had one
|
// Check we had one
|
||||||
|
@ -97,8 +97,6 @@ const getTransactor = (): string => {
|
|||||||
export interface Account {
|
export interface Account {
|
||||||
_id: ObjectId
|
_id: ObjectId
|
||||||
email: string
|
email: string
|
||||||
first: string
|
|
||||||
last: string
|
|
||||||
hash: Binary
|
hash: Binary
|
||||||
salt: Binary
|
salt: Binary
|
||||||
workspaces: ObjectId[]
|
workspaces: ObjectId[]
|
||||||
@ -349,12 +347,14 @@ export async function join (
|
|||||||
productId: string,
|
productId: string,
|
||||||
email: string,
|
email: string,
|
||||||
password: string,
|
password: string,
|
||||||
|
firstName: string,
|
||||||
|
lastName: string,
|
||||||
inviteId: ObjectId
|
inviteId: ObjectId
|
||||||
): Promise<WorkspaceLoginInfo> {
|
): Promise<WorkspaceLoginInfo> {
|
||||||
const invite = await getInvite(db, inviteId)
|
const invite = await getInvite(db, inviteId)
|
||||||
const workspace = await checkInvite(invite, email)
|
const workspace = await checkInvite(invite, email)
|
||||||
console.log(`join attempt:${email}, ${workspace.name}`)
|
console.log(`join attempt:${email}, ${workspace.name}`)
|
||||||
await assignWorkspace(db, productId, email, workspace.name)
|
await assignWorkspace(db, productId, email, workspace.name, firstName, lastName)
|
||||||
|
|
||||||
const token = (await login(db, productId, email, password)).token
|
const token = (await login(db, productId, email, password)).token
|
||||||
const result = await selectWorkspace(db, productId, token, workspace.name)
|
const result = await selectWorkspace(db, productId, token, workspace.name)
|
||||||
@ -470,8 +470,8 @@ export async function signUpJoin (
|
|||||||
console.log(`signup join:${email} ${first} ${last}`)
|
console.log(`signup join:${email} ${first} ${last}`)
|
||||||
const invite = await getInvite(db, inviteId)
|
const invite = await getInvite(db, inviteId)
|
||||||
const workspace = await checkInvite(invite, email)
|
const workspace = await checkInvite(invite, email)
|
||||||
await createAcc(db, productId, email, password, first, last, invite?.emailMask === email)
|
await createAcc(db, productId, email, password, invite?.emailMask === email)
|
||||||
await assignWorkspace(db, productId, email, workspace.name)
|
await assignWorkspace(db, productId, email, workspace.name, first, last)
|
||||||
|
|
||||||
const token = (await login(db, productId, email, password)).token
|
const token = (await login(db, productId, email, password)).token
|
||||||
const result = await selectWorkspace(db, productId, token, workspace.name)
|
const result = await selectWorkspace(db, productId, token, workspace.name)
|
||||||
@ -487,8 +487,6 @@ export async function createAcc (
|
|||||||
productId: string,
|
productId: string,
|
||||||
email: string,
|
email: string,
|
||||||
password: string,
|
password: string,
|
||||||
first: string,
|
|
||||||
last: string,
|
|
||||||
confirmed: boolean = false
|
confirmed: boolean = false
|
||||||
): Promise<Account> {
|
): Promise<Account> {
|
||||||
const salt = randomBytes(32)
|
const salt = randomBytes(32)
|
||||||
@ -508,8 +506,6 @@ export async function createAcc (
|
|||||||
email,
|
email,
|
||||||
hash,
|
hash,
|
||||||
salt,
|
salt,
|
||||||
first,
|
|
||||||
last,
|
|
||||||
confirmed,
|
confirmed,
|
||||||
workspaces: []
|
workspaces: []
|
||||||
})
|
})
|
||||||
@ -527,15 +523,8 @@ export async function createAcc (
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export async function createAccount (
|
export async function createAccount (db: Db, productId: string, email: string, password: string): Promise<LoginInfo> {
|
||||||
db: Db,
|
const account = await createAcc(db, productId, email, password, false)
|
||||||
productId: string,
|
|
||||||
email: string,
|
|
||||||
password: string,
|
|
||||||
first: string,
|
|
||||||
last: string
|
|
||||||
): Promise<LoginInfo> {
|
|
||||||
const account = await createAcc(db, productId, email, password, first, last, false)
|
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
endpoint: getEndpoint(),
|
endpoint: getEndpoint(),
|
||||||
@ -634,7 +623,14 @@ export async function upgradeWorkspace (
|
|||||||
*/
|
*/
|
||||||
export const createUserWorkspace =
|
export const createUserWorkspace =
|
||||||
(version: Data<Version>, txes: Tx[], migrationOperation: [string, MigrateOperation][]) =>
|
(version: Data<Version>, txes: Tx[], migrationOperation: [string, MigrateOperation][]) =>
|
||||||
async (db: Db, productId: string, token: string, workspace: string): Promise<LoginInfo> => {
|
async (
|
||||||
|
db: Db,
|
||||||
|
productId: string,
|
||||||
|
token: string,
|
||||||
|
workspace: string,
|
||||||
|
firstName: string,
|
||||||
|
lastName: string
|
||||||
|
): Promise<LoginInfo> => {
|
||||||
if (!/^[0-9a-z][0-9a-z-]{2,62}[0-9a-z]$/.test(workspace)) {
|
if (!/^[0-9a-z][0-9a-z-]{2,62}[0-9a-z]$/.test(workspace)) {
|
||||||
throw new PlatformError(new Status(Severity.ERROR, platform.status.InvalidId, { id: workspace }))
|
throw new PlatformError(new Status(Severity.ERROR, platform.status.InvalidId, { id: workspace }))
|
||||||
}
|
}
|
||||||
@ -682,7 +678,7 @@ export const createUserWorkspace =
|
|||||||
// Update last workspace time.
|
// Update last workspace time.
|
||||||
await db.collection(ACCOUNT_COLLECTION).updateOne({ _id: info._id }, { $set: { lastWorkspace: Date.now() } })
|
await db.collection(ACCOUNT_COLLECTION).updateOne({ _id: info._id }, { $set: { lastWorkspace: Date.now() } })
|
||||||
|
|
||||||
await assignWorkspace(db, productId, email, workspace)
|
await assignWorkspace(db, productId, email, workspace, firstName, lastName)
|
||||||
await setRole(email, workspace, productId, AccountRole.Owner)
|
await setRole(email, workspace, productId, AccountRole.Owner)
|
||||||
const result = {
|
const result = {
|
||||||
endpoint: getEndpoint(),
|
endpoint: getEndpoint(),
|
||||||
@ -791,7 +787,14 @@ export async function setRole (email: string, workspace: string, productId: stri
|
|||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export async function assignWorkspace (db: Db, productId: string, email: string, workspace: string): Promise<void> {
|
export async function assignWorkspace (
|
||||||
|
db: Db,
|
||||||
|
productId: string,
|
||||||
|
email: string,
|
||||||
|
workspace: string,
|
||||||
|
firstName: string,
|
||||||
|
lastName: string
|
||||||
|
): Promise<void> {
|
||||||
const initWS = getMetadata(toolPlugin.metadata.InitWorkspace)
|
const initWS = getMetadata(toolPlugin.metadata.InitWorkspace)
|
||||||
if (initWS !== undefined && initWS === workspace) {
|
if (initWS !== undefined && initWS === workspace) {
|
||||||
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
|
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
|
||||||
@ -799,7 +802,7 @@ export async function assignWorkspace (db: Db, productId: string, email: string,
|
|||||||
const { workspaceId, accountId } = await getWorkspaceAndAccount(db, productId, email, workspace)
|
const { workspaceId, accountId } = await getWorkspaceAndAccount(db, productId, email, workspace)
|
||||||
const account = await db.collection<Account>(ACCOUNT_COLLECTION).findOne({ _id: accountId })
|
const account = await db.collection<Account>(ACCOUNT_COLLECTION).findOne({ _id: accountId })
|
||||||
|
|
||||||
if (account !== null) await createPersonAccount(account, productId, workspace)
|
if (account !== null) await createPersonAccount(account, productId, workspace, firstName, lastName)
|
||||||
|
|
||||||
// Add account into workspace.
|
// Add account into workspace.
|
||||||
await db.collection(WORKSPACE_COLLECTION).updateOne({ _id: workspaceId }, { $addToSet: { accounts: accountId } })
|
await db.collection(WORKSPACE_COLLECTION).updateOne({ _id: workspaceId }, { $addToSet: { accounts: accountId } })
|
||||||
@ -833,12 +836,18 @@ async function createEmployee (ops: TxOperations, name: string, email: string):
|
|||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createPersonAccount (account: Account, productId: string, workspace: string): Promise<void> {
|
async function createPersonAccount (
|
||||||
|
account: Account,
|
||||||
|
productId: string,
|
||||||
|
workspace: string,
|
||||||
|
firstName: string,
|
||||||
|
lastName: string
|
||||||
|
): Promise<void> {
|
||||||
const connection = await connect(getTransactor(), getWorkspaceId(workspace, productId))
|
const connection = await connect(getTransactor(), getWorkspaceId(workspace, productId))
|
||||||
try {
|
try {
|
||||||
const ops = new TxOperations(connection, core.account.System)
|
const ops = new TxOperations(connection, core.account.System)
|
||||||
|
|
||||||
const name = combineName(account.first, account.last)
|
const name = combineName(firstName, lastName)
|
||||||
// Check if EmployeeAccoun is not exists
|
// Check if EmployeeAccoun is not exists
|
||||||
const existingAccount = await ops.findOne(contact.class.PersonAccount, { email: account.email })
|
const existingAccount = await ops.findOne(contact.class.PersonAccount, { email: account.email })
|
||||||
if (existingAccount === undefined) {
|
if (existingAccount === undefined) {
|
||||||
@ -847,7 +856,6 @@ async function createPersonAccount (account: Account, productId: string, workspa
|
|||||||
await ops.createDoc(contact.class.PersonAccount, core.space.Model, {
|
await ops.createDoc(contact.class.PersonAccount, core.space.Model, {
|
||||||
email: account.email,
|
email: account.email,
|
||||||
person: employee,
|
person: employee,
|
||||||
name,
|
|
||||||
role: 0
|
role: 0
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -975,57 +983,6 @@ export async function restorePassword (db: Db, productId: string, token: string,
|
|||||||
return await login(db, productId, email, password)
|
return await login(db, productId, email, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export async function changeName (db: Db, productId: string, token: string, first: string, last: string): Promise<void> {
|
|
||||||
const { email } = decodeToken(token)
|
|
||||||
const account = await getAccount(db, email)
|
|
||||||
if (account === null) {
|
|
||||||
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, { account: email }))
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.collection<Account>(ACCOUNT_COLLECTION).updateOne({ _id: account._id }, { $set: { first, last } })
|
|
||||||
account.first = first
|
|
||||||
account.last = last
|
|
||||||
|
|
||||||
const workspaces = await db
|
|
||||||
.collection<Workspace>(WORKSPACE_COLLECTION)
|
|
||||||
.find(withProductId(productId, { _id: { $in: account.workspaces } }))
|
|
||||||
.toArray()
|
|
||||||
|
|
||||||
const promises: Promise<void>[] = []
|
|
||||||
for (const ws of workspaces) {
|
|
||||||
promises.push(updatePersonAccount(account, ws.workspace, ws.productId))
|
|
||||||
}
|
|
||||||
await Promise.all(promises)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updatePersonAccount (account: Account, workspace: string, productId: string): Promise<void> {
|
|
||||||
const connection = await connect(getTransactor(), getWorkspaceId(workspace, productId), account.email)
|
|
||||||
try {
|
|
||||||
const ops = new TxOperations(connection, core.account.System)
|
|
||||||
|
|
||||||
const name = combineName(account.first, account.last)
|
|
||||||
|
|
||||||
const employeeAccount = await ops.findOne(contact.class.PersonAccount, { email: account.email })
|
|
||||||
if (employeeAccount === undefined) return
|
|
||||||
|
|
||||||
await ops.update(employeeAccount, {
|
|
||||||
name
|
|
||||||
})
|
|
||||||
|
|
||||||
const employee = await ops.findOne(contact.mixin.Employee, { _id: employeeAccount.person as Ref<Employee> })
|
|
||||||
if (employee === undefined) return
|
|
||||||
|
|
||||||
await ops.update(employee, {
|
|
||||||
name
|
|
||||||
})
|
|
||||||
} finally {
|
|
||||||
await connection.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -1246,7 +1203,6 @@ export function getMethods (
|
|||||||
removeWorkspace: wrap(removeWorkspace),
|
removeWorkspace: wrap(removeWorkspace),
|
||||||
leaveWorkspace: wrap(leaveWorkspace),
|
leaveWorkspace: wrap(leaveWorkspace),
|
||||||
listWorkspaces: wrap(listWorkspaces),
|
listWorkspaces: wrap(listWorkspaces),
|
||||||
changeName: wrap(changeName),
|
|
||||||
changePassword: wrap(changePassword),
|
changePassword: wrap(changePassword),
|
||||||
requestPassword: wrap(requestPassword),
|
requestPassword: wrap(requestPassword),
|
||||||
restorePassword: wrap(restorePassword),
|
restorePassword: wrap(restorePassword),
|
||||||
|
@ -42,7 +42,6 @@ export async function getUser (storage: ServerStorage, ctx: SessionContext): Pro
|
|||||||
role: AccountRole.Owner,
|
role: AccountRole.Owner,
|
||||||
email: systemAccountEmail,
|
email: systemAccountEmail,
|
||||||
space: core.space.Model,
|
space: core.space.Model,
|
||||||
name: core.string.System,
|
|
||||||
modifiedBy: core.account.System,
|
modifiedBy: core.account.System,
|
||||||
modifiedOn: 0
|
modifiedOn: 0
|
||||||
}
|
}
|
||||||
|
@ -199,8 +199,8 @@ export function genMinModel (): TxCUD<Doc>[] {
|
|||||||
const u1 = 'User1' as Ref<Account>
|
const u1 = 'User1' as Ref<Account>
|
||||||
const u2 = 'User2' as Ref<Account>
|
const u2 = 'User2' as Ref<Account>
|
||||||
txes.push(
|
txes.push(
|
||||||
createDoc(core.class.Account, { email: 'user1@site.com', name: '1', role: 0 }, u1),
|
createDoc(core.class.Account, { email: 'user1@site.com', role: 0 }, u1),
|
||||||
createDoc(core.class.Account, { email: 'user2@site.com', name: '2', role: 0 }, u2),
|
createDoc(core.class.Account, { email: 'user2@site.com', role: 0 }, u2),
|
||||||
createDoc(core.class.Space, {
|
createDoc(core.class.Space, {
|
||||||
name: 'Sp1',
|
name: 'Sp1',
|
||||||
description: '',
|
description: '',
|
||||||
|
@ -174,8 +174,8 @@ export function genMinModel (): TxCUD<Doc>[] {
|
|||||||
const u1 = 'User1' as Ref<Account>
|
const u1 = 'User1' as Ref<Account>
|
||||||
const u2 = 'User2' as Ref<Account>
|
const u2 = 'User2' as Ref<Account>
|
||||||
txes.push(
|
txes.push(
|
||||||
createDoc(core.class.Account, { email: 'user1@site.com', name: 'test1', role: 0 }, u1),
|
createDoc(core.class.Account, { email: 'user1@site.com', role: 0 }, u1),
|
||||||
createDoc(core.class.Account, { email: 'user2@site.com', name: 'test2', role: 0 }, u2),
|
createDoc(core.class.Account, { email: 'user2@site.com', role: 0 }, u2),
|
||||||
createDoc(core.class.Space, {
|
createDoc(core.class.Space, {
|
||||||
name: 'Sp1',
|
name: 'Sp1',
|
||||||
description: '',
|
description: '',
|
||||||
|
@ -10,7 +10,7 @@ export SERVER_SECRET=secret
|
|||||||
# Create workspace record in accounts
|
# Create workspace record in accounts
|
||||||
node ../dev/tool/bundle.js create-workspace sanity-ws -o SanityTest
|
node ../dev/tool/bundle.js create-workspace sanity-ws -o SanityTest
|
||||||
# Create user record in accounts
|
# Create user record in accounts
|
||||||
node ../dev/tool/bundle.js create-account user1 -f John -l Appleseed -p 1234
|
node ../dev/tool/bundle.js create-account user1 -p 1234
|
||||||
node ../dev/tool/bundle.js confirm-email user1
|
node ../dev/tool/bundle.js confirm-email user1
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ node ../dev/tool/bundle.js backup-restore ./sanity-ws sanity-ws
|
|||||||
node ../dev/tool/bundle.js upgrade-workspace sanity-ws
|
node ../dev/tool/bundle.js upgrade-workspace sanity-ws
|
||||||
|
|
||||||
# Re-assign user to workspace.
|
# Re-assign user to workspace.
|
||||||
node ../dev/tool/bundle.js assign-workspace user1 sanity-ws
|
node ../dev/tool/bundle.js assign-workspace user1 sanity-ws -f John -l Appleseed
|
||||||
|
|
||||||
node ../dev/tool/bundle.js configure sanity-ws --enable=*
|
node ../dev/tool/bundle.js configure sanity-ws --enable=*
|
||||||
node ../dev/tool/bundle.js configure sanity-ws --list
|
node ../dev/tool/bundle.js configure sanity-ws --list
|
@ -9,7 +9,7 @@ docker-compose -p sanity up -d --force-recreate --renew-anon-volumes
|
|||||||
# Create workspace record in accounts
|
# Create workspace record in accounts
|
||||||
./tool.sh create-workspace sanity-ws -o SanityTest
|
./tool.sh create-workspace sanity-ws -o SanityTest
|
||||||
# Create user record in accounts
|
# Create user record in accounts
|
||||||
./tool.sh create-account user1 -f John -l Appleseed -p 1234
|
./tool.sh create-account user1 -p 1234
|
||||||
# Make user the workspace maintainer
|
# Make user the workspace maintainer
|
||||||
./tool.sh set-user-role user1 sanity-ws 1
|
./tool.sh set-user-role user1 sanity-ws 1
|
||||||
./tool.sh confirm-email user1
|
./tool.sh confirm-email user1
|
||||||
|
@ -13,7 +13,7 @@ node ../dev/tool/bundle.js backup-restore ./sanity-ws sanity-ws
|
|||||||
node ../dev/tool/bundle.js upgrade-workspace sanity-ws
|
node ../dev/tool/bundle.js upgrade-workspace sanity-ws
|
||||||
|
|
||||||
# Re-assign user to workspace.
|
# Re-assign user to workspace.
|
||||||
node ../dev/tool/bundle.js assign-workspace user1 sanity-ws
|
node ../dev/tool/bundle.js assign-workspace user1 sanity-ws -f John -l Appleseed
|
||||||
|
|
||||||
node ../dev/tool/bundle.js configure sanity-ws --enable=*
|
node ../dev/tool/bundle.js configure sanity-ws --enable=*
|
||||||
node ../dev/tool/bundle.js configure sanity-ws --list
|
node ../dev/tool/bundle.js configure sanity-ws --list
|
@ -6,7 +6,7 @@
|
|||||||
./tool.sh upgrade-workspace sanity-ws
|
./tool.sh upgrade-workspace sanity-ws
|
||||||
|
|
||||||
# Re-assign user to workspace.
|
# Re-assign user to workspace.
|
||||||
./tool.sh assign-workspace user1 sanity-ws
|
./tool.sh assign-workspace user1 sanity-ws -f John -l Appleseed
|
||||||
|
|
||||||
./tool.sh configure sanity-ws --enable=*
|
./tool.sh configure sanity-ws --enable=*
|
||||||
./tool.sh configure sanity-ws --list
|
./tool.sh configure sanity-ws --list
|
||||||
|
Loading…
Reference in New Issue
Block a user