diff --git a/dev/tool/src/index.ts b/dev/tool/src/index.ts index e2ae3c88d1..5c54f9f4d9 100644 --- a/dev/tool/src/index.ts +++ b/dev/tool/src/index.ts @@ -1140,49 +1140,51 @@ export function devTool ( .option('-bl, --blobLimit ', 'A blob size limit in megabytes (default 50mb)', '50') .option('-c, --concurrency ', 'Number of files being processed concurrently', '10') .option('--disabled', 'Include disabled workspaces', false) - .action(async (cmd: { workspace: string, move: string, blobLimit: string, concurrency: string, disabled: boolean }) => { - const params = { - blobSizeLimitMb: parseInt(cmd.blobLimit), - concurrency: parseInt(cmd.concurrency), - move: cmd.move === 'true' - } + .action( + async (cmd: { workspace: string, move: string, blobLimit: string, concurrency: string, disabled: boolean }) => { + const params = { + blobSizeLimitMb: parseInt(cmd.blobLimit), + concurrency: parseInt(cmd.concurrency), + move: cmd.move === 'true' + } - const { mongodbUri } = prepareTools() - await withDatabase(mongodbUri, async (db) => { - await withStorage(mongodbUri, async (adapter) => { - try { - const exAdapter = adapter as StorageAdapterEx - if (exAdapter.adapters === undefined || exAdapter.adapters.size < 2) { - throw new Error('bad storage config, at least two storage providers are required') - } - - console.log('moving files to storage provider', exAdapter.defaultAdapter) - - let index = 1 - const workspaces = await listWorkspacesPure(db) - workspaces.sort((a, b) => b.lastVisit - a.lastVisit) - - for (const workspace of workspaces) { - if (cmd.workspace !== '' && workspace.workspace !== cmd.workspace) { - continue - } - if (workspace.disabled === true && !cmd.disabled) { - console.log('ignore disabled workspace', workspace.workspace) - continue + const { mongodbUri } = prepareTools() + await withDatabase(mongodbUri, async (db) => { + await withStorage(mongodbUri, async (adapter) => { + try { + const exAdapter = adapter as StorageAdapterEx + if (exAdapter.adapters === undefined || exAdapter.adapters.size < 2) { + throw new Error('bad storage config, at least two storage providers are required') } - console.log('start', workspace.workspace, index, '/', workspaces.length) - await moveFiles(toolCtx, getWorkspaceId(workspace.workspace), exAdapter, params) - console.log('done', workspace.workspace) + console.log('moving files to storage provider', exAdapter.defaultAdapter) - index += 1 + let index = 1 + const workspaces = await listWorkspacesPure(db) + workspaces.sort((a, b) => b.lastVisit - a.lastVisit) + + for (const workspace of workspaces) { + if (cmd.workspace !== '' && workspace.workspace !== cmd.workspace) { + continue + } + if (workspace.disabled === true && !cmd.disabled) { + console.log('ignore disabled workspace', workspace.workspace) + continue + } + + console.log('start', workspace.workspace, index, '/', workspaces.length) + await moveFiles(toolCtx, getWorkspaceId(workspace.workspace), exAdapter, params) + console.log('done', workspace.workspace) + + index += 1 + } + } catch (err: any) { + console.error(err) } - } catch (err: any) { - console.error(err) - } + }) }) - }) - }) + } + ) program .command('sync-files') diff --git a/models/notification/src/index.ts b/models/notification/src/index.ts index cc076d5782..07a35e3fde 100644 --- a/models/notification/src/index.ts +++ b/models/notification/src/index.ts @@ -105,6 +105,10 @@ export class TBrowserNotification extends TDoc implements BrowserNotification { onClickLocation?: Location | undefined user!: Ref status!: NotificationStatus + messageId?: Ref + messageClass?: Ref> + objectId!: Ref + objectClass!: Ref> } @Model(notification.class.PushSubscription, core.class.Doc, DOMAIN_USER_NOTIFY) diff --git a/models/time/src/plugin.ts b/models/time/src/plugin.ts index 28c07b59e2..19b134da99 100644 --- a/models/time/src/plugin.ts +++ b/models/time/src/plugin.ts @@ -34,7 +34,6 @@ export default mergeIds(timeId, time, { EditToDo: '' as IntlString, GotoTimePlaning: '' as IntlString, GotoTimeTeamPlaning: '' as IntlString, - NewToDo: '' as IntlString, Priority: '' as IntlString, MarkedAsDone: '' as IntlString }, diff --git a/packages/theme/styles/button.scss b/packages/theme/styles/button.scss index 53820dbcfa..df341e369a 100644 --- a/packages/theme/styles/button.scss +++ b/packages/theme/styles/button.scss @@ -1,3 +1,177 @@ +.hulyButton { + display: inline-flex; + justify-content: center; + align-items: center; + flex-shrink: 0; + gap: var(--spacing-1); + border: 1px solid transparent; + + &:not(:disabled, .disabled, .loading) { cursor: pointer; } + &.inheritFont { font: inherit; } + + .icon { + display: flex; + align-items: center; + justify-content: center; + width: var(--spacing-2_5); + height: var(--spacing-2_5); + } + span { white-space: nowrap; } + + &:focus { + outline: 2px solid var(--global-focus-BorderColor); + outline-offset: 2px; + } + &.type-button-icon { padding: 0; } + &.large { + height: var(--global-large-Size); + border-radius: var(--medium-BorderRadius); + + &.round { border-radius: var(--large-BorderRadius); } + + &.type-button:not(.iconOnly) { padding: 0 var(--spacing-2); } + &.iconOnly, + &.type-button-icon { width: var(--global-large-Size); } + } + &.medium { + height: var(--global-medium-Size); + border-radius: var(--medium-BorderRadius); + + &.round { border-radius: var(--large-BorderRadius); } + &.type-button:not(.iconOnly) { padding: 0 var(--spacing-2); } + &.iconOnly, + &.type-button-icon { width: var(--global-medium-Size); } + } + &.small { + height: var(--global-small-Size); + gap: var(--spacing-0_5); + border-radius: var(--small-BorderRadius); + + &.round { border-radius: var(--large-BorderRadius); } + &.type-button:not(.iconOnly) { padding: 0 var(--spacing-1); } + &.iconOnly, + &.type-button-icon { width: var(--global-small-Size); } + } + &.extra-small { + height: var(--global-extra-small-Size); + border-radius: var(--extra-small-BorderRadius); + + &.round { border-radius: var(--large-BorderRadius); } + &.type-button:not(.iconOnly) { padding: 0 var(--spacing-1); } + &.iconOnly, + &.type-button-icon { width: var(--global-extra-small-Size); } + } + &.min { + height: var(--global-min-Size); + border: 0; + border-radius: var(--min-BorderRadius); + } + &.type-button-icon .icon, + &.menu .icon { + width: var(--spacing-2); + height: var(--spacing-2); + } + + &:disabled:not(.loading), + &.disabled:not(.loading) { + border-color: transparent; + cursor: not-allowed; + + .icon { color: var(--button-disabled-IconColor); } + span { color: var(--button-disabled-LabelColor); } + } + + &.primary { + border-color: var(--button-primary-BorderColor); + background-color: var(--button-primary-BackgroundColor); + + .icon { color: var(--button-accent-IconColor); } + span { color: var(--button-accent-LabelColor); } + + &:not(.disabled, :disabled):hover { background-color: var(--button-primary-hover-BackgroundColor); } + &:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { background-color: var(--button-primary-active-BackgroundColor); } + &.menu:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { border-color: var(--button-menu-active-BorderColor); } + &:disabled:not(.loading), + &.disabled:not(.loading) { background-color: var(--button-disabled-BackgroundColor); } + &.loading { + background-color: var(--button-primary-active-BackgroundColor); + + span { color: var(--button-primary-loading-LabelColor); } + } + } + + &.secondary { + border-color: var(--button-secondary-BorderColor); + background-color: var(--button-secondary-BackgroundColor); + + .icon { color: var(--button-subtle-IconColor); } + span { color: var(--button-subtle-LabelColor); } + + &:not(.disabled, :disabled):hover { background-color: var(--button-secondary-hover-BackgroundColor); } + &:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { background-color: var(--button-secondary-active-BackgroundColor); } + &.menu:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { border-color: var(--button-menu-active-BorderColor); } + &:disabled:not(.loading), + &.disabled:not(.loading) { background-color: var(--button-disabled-BackgroundColor); } + &.loading { + background-color: var(--button-secondary-active-BackgroundColor); + + span { color: var(--button-disabled-LabelColor); } + } + } + + &.tertiary { + border-color: transparent; + background-color: transparent; + + &:not(.inheritColor) .icon { color: var(--button-subtle-IconColor); } + &.inheritColor { + color: inherit; + + .icon { color: currentColor; } + } + span { color: var(--button-subtle-LabelColor); } + + &:not(.disabled, :disabled):hover { background-color: var(--button-tertiary-hover-BackgroundColor); } + &:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { background-color: var(--button-tertiary-active-BackgroundColor); } + &.menu:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { border-color: var(--button-menu-active-BorderColor); } + &.loading { + background-color: var(--button-tertiary-active-BackgroundColor); + + span { color: var(--button-disabled-LabelColor); } + } + } + + &.negative { + border-color: var(--button-negative-BorderColor); + background-color: var(--button-negative-BackgroundColor); + + .icon { color: var(--button-accent-IconColor); } + span { color: var(--button-accent-LabelColor); } + + &:not(.disabled, :disabled):hover { background-color: var(--button-negative-hover-BackgroundColor); } + &:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { background-color: var(--button-negative-active-BackgroundColor); } + &.menu:not(.disabled, :disabled):active, + &.pressed:not(.disabled, :disabled) { border-color: var(--button-menu-active-BorderColor); } + &:disabled:not(.loading), + &.disabled:not(.loading) { background-color: var(--button-disabled-BackgroundColor); } + &.loading { + background-color: var(--button-negative-active-BackgroundColor); + + span { color: var(--button-negative-loading-LabelColor); } + } + } + + & > * { pointer-events: none; } +} + +// Old style Button .antiButton { display: flex; align-items: center; diff --git a/packages/ui/src/components/ButtonBase.svelte b/packages/ui/src/components/ButtonBase.svelte index 487cd96623..1acf7c107b 100644 --- a/packages/ui/src/components/ButtonBase.svelte +++ b/packages/ui/src/components/ButtonBase.svelte @@ -92,7 +92,7 @@ - - diff --git a/packages/ui/src/components/calendar/TimeInputBox.svelte b/packages/ui/src/components/calendar/TimeInputBox.svelte index f3b19b3e8e..dc3cb5466b 100644 --- a/packages/ui/src/components/calendar/TimeInputBox.svelte +++ b/packages/ui/src/components/calendar/TimeInputBox.svelte @@ -153,7 +153,7 @@ } } } - const focused = (ed: TEdits): void => { + export const focused = (ed: TEdits): void => { selected = ed startTyping = true } diff --git a/plugins/calendar-resources/src/components/DateEditor.svelte b/plugins/calendar-resources/src/components/DateEditor.svelte index 1795edd5bf..2ab809b2c4 100644 --- a/plugins/calendar-resources/src/components/DateEditor.svelte +++ b/plugins/calendar-resources/src/components/DateEditor.svelte @@ -31,7 +31,7 @@ export let date: number export let difference: number = 0 - export let direction: 'vertical' | 'horizontal' = 'vertical' + export let direction: 'vertical' | 'horizontal' | 'auto' = 'vertical' export let showDate: boolean = true export let withoutTime: boolean export let kind: ButtonBaseKind = 'tertiary' @@ -44,8 +44,9 @@ const dispatch = createEventDispatcher() $: currentDate = new Date(date) + let tib: TimeInputBox - function timeClick (e: MouseEvent) { + function timeClick (e: MouseEvent & { currentTarget: EventTarget & HTMLElement }) { if (!showDate) { showPopup( DatePopup, @@ -58,7 +59,7 @@ } } ) - } + } else if (!disabled) tib.focused(e.offsetX <= e.currentTarget.clientWidth / 2 ? 'hour' : 'min') } function dateClick (e: MouseEvent) { @@ -85,13 +86,17 @@ {#if fixed === undefined}
- + + +
{:else} - + + + {/if} @@ -103,15 +108,17 @@ {#if !withoutTime} {#if fixed === undefined} - + + +
- +
{:else} - + + +
- +
{/if} {/if} @@ -162,9 +171,15 @@ diff --git a/plugins/chunter-resources/src/components/threads/ThreadView.svelte b/plugins/chunter-resources/src/components/threads/ThreadView.svelte index 9a249b28de..f6c386e228 100644 --- a/plugins/chunter-resources/src/components/threads/ThreadView.svelte +++ b/plugins/chunter-resources/src/components/threads/ThreadView.svelte @@ -15,7 +15,7 @@ {#if showHeader} @@ -153,54 +141,10 @@ {/if} -
- {#if message && dataProvider !== undefined} - - -
- -
- - {#if (message.replies ?? $messagesStore?.length ?? 0) > 0} -
-
-
-
-
- {/if} - - - {/if} -
- - +{#if message} + {#key _id} + + {/key} +{:else if isLoading} + +{/if} diff --git a/plugins/chunter-resources/src/navigation.ts b/plugins/chunter-resources/src/navigation.ts index 6e9cf29e75..9281c98fa2 100644 --- a/plugins/chunter-resources/src/navigation.ts +++ b/plugins/chunter-resources/src/navigation.ts @@ -28,6 +28,7 @@ import { get } from 'svelte/store' import { chatSpecials } from './components/chat/utils' import { getChannelName, isThreadMessage } from './utils' import chunter from './plugin' +import { threadMessagesStore } from './stores' export function openChannel (_id: string, _class: Ref>, thread?: Ref): void { const loc = getCurrentLocation() @@ -168,6 +169,8 @@ export async function replyToThread (message: ActivityMessage, e: Event): Promis const fromSidebar = isElementFromSidebar(e.target as HTMLElement) const loc = getCurrentLocation() + threadMessagesStore.set(message) + if (fromSidebar) { const widget = getClient().getModel().findAllSync(workbench.class.Widget, { _id: chunter.ids.ChatWidget })[0] const widgetState = get(sidebarStore).widgetsState.get(widget._id) @@ -235,7 +238,8 @@ export async function openChannelInSidebar ( _class: Ref>, doc?: Doc, thread?: Ref, - newTab = true + newTab = true, + selectedMessageId?: Ref ): Promise { const client = getClient() @@ -267,6 +271,7 @@ export async function openChannelInSidebar ( _id, _class, thread, + selectedMessageId, channelName: name } } diff --git a/plugins/chunter-resources/src/stores.ts b/plugins/chunter-resources/src/stores.ts index 789c8a702d..03b1b787ad 100644 --- a/plugins/chunter-resources/src/stores.ts +++ b/plugins/chunter-resources/src/stores.ts @@ -17,11 +17,14 @@ import { writable } from 'svelte/store' import { type ChatMessage } from '@hcengineering/chunter' import { type Markup, type Ref } from '@hcengineering/core' import { languageStore } from '@hcengineering/ui' +import { type ActivityMessage } from '@hcengineering/activity' export const translatingMessagesStore = writable>>(new Set()) export const translatedMessagesStore = writable, Markup>>(new Map()) export const shownTranslatedMessagesStore = writable>>(new Set()) +export const threadMessagesStore = writable(undefined) + languageStore.subscribe(() => { translatedMessagesStore.set(new Map()) shownTranslatedMessagesStore.set(new Set()) diff --git a/plugins/chunter/src/index.ts b/plugins/chunter/src/index.ts index 3c814160b9..662ea1e23d 100644 --- a/plugins/chunter/src/index.ts +++ b/plugins/chunter/src/index.ts @@ -100,7 +100,13 @@ export interface InlineButton extends AttachedDoc { } export interface ChatWidgetTab extends WidgetTab { - data: { _id?: Ref, _class?: Ref>, thread?: Ref, channelName: string } + data: { + _id?: Ref + _class?: Ref> + thread?: Ref + channelName: string + selectedMessageId?: Ref + } } /** @@ -234,7 +240,14 @@ export default plugin(chunterId, { CanTranslateMessage: '' as Resource<(doc?: Doc | Doc[]) => Promise>, OpenThreadInSidebar: '' as Resource<(_id: Ref, msg?: ActivityMessage, doc?: Doc) => Promise>, OpenChannelInSidebar: '' as Resource< - (_id: Ref, _class: Ref, doc?: Doc, thread?: Ref) => Promise + ( + _id: Ref, + _class: Ref>, + doc?: Doc, + thread?: Ref, + newTab?: boolean, + selectedMessageId?: Ref + ) => Promise > } }) diff --git a/plugins/notification-resources/src/components/DocNotifyContextCard.svelte b/plugins/notification-resources/src/components/DocNotifyContextCard.svelte index d9c8b7ef75..206e845674 100644 --- a/plugins/notification-resources/src/components/DocNotifyContextCard.svelte +++ b/plugins/notification-resources/src/components/DocNotifyContextCard.svelte @@ -64,6 +64,7 @@ $: if (object !== undefined && object?._id !== value.objectId) { object = undefined + isLoading = true } let isActionMenuOpened = false diff --git a/plugins/notification-resources/src/components/Notification.svelte b/plugins/notification-resources/src/components/Notification.svelte index e76f6c5ae8..0fd5045cee 100644 --- a/plugins/notification-resources/src/components/Notification.svelte +++ b/plugins/notification-resources/src/components/Notification.svelte @@ -1,13 +1,14 @@ @@ -56,7 +77,7 @@
{/each} diff --git a/plugins/time/src/index.ts b/plugins/time/src/index.ts index 7e3d6d6982..49b695a6e4 100644 --- a/plugins/time/src/index.ts +++ b/plugins/time/src/index.ts @@ -160,6 +160,7 @@ export default plugin(timeId, { CreatedToDo: '' as IntlString, AddToDo: '' as IntlString, NewToDoDetails: '' as IntlString, - ToDo: '' as IntlString + ToDo: '' as IntlString, + NewToDo: '' as IntlString } }) diff --git a/plugins/workbench-resources/src/sidebar.ts b/plugins/workbench-resources/src/sidebar.ts index ee1ff76cdd..8be7c826bf 100644 --- a/plugins/workbench-resources/src/sidebar.ts +++ b/plugins/workbench-resources/src/sidebar.ts @@ -316,3 +316,20 @@ export function minimizeSidebar (closedByUser = false): void { sidebarStore.set({ ...state, ...widgetsState, widget: undefined, variant: SidebarVariant.MINI }) } + +export function updateTabData (widget: Ref, tabId: string, data: Record): void { + const state = get(sidebarStore) + const { widgetsState } = state + const widgetState = widgetsState.get(widget) + + if (widgetState === undefined) return + + const tabs = widgetState.tabs.map((it) => (it.id === tabId ? { ...it, data: { ...it.data, ...data } } : it)) + + widgetsState.set(widget, { ...widgetState, tabs }) + + sidebarStore.set({ + ...state, + widgetsState + }) +} diff --git a/server-plugins/notification-resources/src/index.ts b/server-plugins/notification-resources/src/index.ts index a09e410c19..6df2fc5a7f 100644 --- a/server-plugins/notification-resources/src/index.ts +++ b/server-plugins/notification-resources/src/index.ts @@ -175,7 +175,8 @@ export async function getCommonNotificationTxes ( doc, receiver, sender, - subscriptions + subscriptions, + _class ) } @@ -487,6 +488,14 @@ export async function getTranslatedNotificationContent ( return { title: '', body: '' } } +function isReactionMessage (message?: ActivityMessage): boolean { + return ( + message !== undefined && + message._class === activity.class.DocUpdateMessage && + (message as DocUpdateMessage).objectClass === activity.class.Reaction + ) +} + export async function createPushFromInbox ( control: TriggerControl, receiver: ReceiverInfo, @@ -497,10 +506,9 @@ export async function createPushFromInbox ( sender: SenderInfo, _id: Ref, subscriptions: PushSubscription[], - cache: Map, Doc> = new Map, Doc>() + message?: ActivityMessage ): Promise { let { title, body } = await getTranslatedNotificationContent(data, _class, control) - if (title === '' || body === '') { return } @@ -515,13 +523,12 @@ export async function createPushFromInbox ( if (provider !== undefined) { const encodeFn = await getResource(provider.encode) - const doc = cache.get(attachedTo) ?? (await control.findAll(control.ctx, attachedToClass, { _id: attachedTo }))[0] + const doc = (await control.findAll(control.ctx, attachedToClass, { _id: attachedTo }))[0] if (doc === undefined) { return } - cache.set(doc._id, doc) id = await encodeFn(doc, control) } @@ -543,6 +550,12 @@ export async function createPushFromInbox ( body, senderId: sender._id, tag: _id, + objectId: attachedTo, + objectClass: attachedToClass, + messageId: isReactionMessage(message) ? (message?.attachedTo as Ref) : message?._id, + messageClass: isReactionMessage(message) + ? (message?.attachedToClass as Ref>) + : message?._class, onClickLocation: { path } @@ -664,6 +677,7 @@ export async function applyNotificationProviders ( receiver: ReceiverInfo, sender: SenderInfo, subscriptions: PushSubscription[], + _class = notification.class.ActivityInboxNotification, message?: ActivityMessage ): Promise { const resources = control.modelDb.findAllSync(serverNotification.class.NotificationProviderResources, {}) @@ -676,10 +690,11 @@ export async function applyNotificationProviders ( attachedTo, attachedToClass, data, - notification.class.ActivityInboxNotification, + _class, sender, data._id, - subscriptions + subscriptions, + message ) if (pushTx !== undefined) { res.push(pushTx) @@ -796,6 +811,7 @@ export async function getNotificationTxes ( receiver, sender, subscriptions, + notificationData._class, message ) } diff --git a/server/server-pipeline/package.json b/server/server-pipeline/package.json index cd25ceba1e..4614875dfd 100644 --- a/server/server-pipeline/package.json +++ b/server/server-pipeline/package.json @@ -172,6 +172,8 @@ "@hcengineering/github": "^0.6.0", "@hcengineering/github-assets": "^0.6.0", "@hcengineering/server-ai-bot": "^0.6.0", - "@hcengineering/server-ai-bot-resources": "^0.6.0" + "@hcengineering/server-ai-bot-resources": "^0.6.0", + "@hcengineering/time": "^0.6.0", + "@hcengineering/time-assets": "^0.6.0" } } diff --git a/server/server-pipeline/src/internationalization.ts b/server/server-pipeline/src/internationalization.ts index 0a19bc82ed..f0b448a8f6 100644 --- a/server/server-pipeline/src/internationalization.ts +++ b/server/server-pipeline/src/internationalization.ts @@ -33,6 +33,7 @@ import { trackerId } from '@hcengineering/tracker' import { trainingId } from '@hcengineering/training' import { viewId } from '@hcengineering/view' import { workbenchId } from '@hcengineering/workbench' +import { timeId } from '@hcengineering/time' import coreEng from '@hcengineering/core/lang/en.json' import loginEng from '@hcengineering/login-assets/lang/en.json' import platformEng from '@hcengineering/platform/lang/en.json' @@ -68,6 +69,7 @@ import trackerEn from '@hcengineering/tracker-assets/lang/en.json' import trainingEn from '@hcengineering/training-assets/lang/en.json' import viewEn from '@hcengineering/view-assets/lang/en.json' import workbenchEn from '@hcengineering/workbench-assets/lang/en.json' +import timeEn from '@hcengineering/time-assets/lang/en.json' export function registerStringLoaders (): void { addStringsLoader(coreId, async (lang: string) => coreEng) @@ -106,4 +108,5 @@ export function registerStringLoaders (): void { addStringsLoader(productsId, async (lang: string) => productsEn) addStringsLoader(trainingId, async (lang: string) => trainingEn) addStringsLoader(githubId, async (lang: string) => githubEn) + addStringsLoader(timeId, async (lang: string) => timeEn) } diff --git a/services/github/github-resources/src/components/utils.ts b/services/github/github-resources/src/components/utils.ts index 2a49911c2c..5600ca53c7 100644 --- a/services/github/github-resources/src/components/utils.ts +++ b/services/github/github-resources/src/components/utils.ts @@ -24,10 +24,10 @@ export async function onAuthorize (login?: string): Promise { ) const client = getClient() - const config = await client.findOne(github.class.GithubAuthentication, {}) - - if (config !== undefined) { - await client.remove(config) + // Remove old authorizations. + const config = await client.findAll(github.class.GithubAuthentication, {}) + for (const c of config) { + await client.remove(c) } await client.createDoc(github.class.GithubAuthentication, core.space.Workspace, { attachedTo: meId, diff --git a/tests/sanity/tests/model/planning/planning-page.ts b/tests/sanity/tests/model/planning/planning-page.ts index 06f724383b..eb38724e01 100644 --- a/tests/sanity/tests/model/planning/planning-page.ts +++ b/tests/sanity/tests/model/planning/planning-page.ts @@ -59,7 +59,7 @@ export class PlanningPage extends CalendarPage { readonly textPanelToDoDescription = (): Locator => this.panel().locator('div.top-content div.tiptap > p') readonly textPanelDueDate = (): Locator => this.panel().locator( - 'div.slots-content div.flex-row-top.justify-between div.flex-row-center button:first-child span' + 'div.slots-content div.flex-row-top.justify-between div.flex-row-center .hulyButton:first-child span' ) readonly textPanelPriority = (): Locator => this.panel().locator('button#priorityButton svg') @@ -189,7 +189,7 @@ export class PlanningPage extends CalendarPage { const row = this.page.locator(p).nth(rowNumber) // dateStart - await row.locator('div.dateEditor-container:first-child > div.min-w-28:first-child button').click() + await row.locator('div.dateEditor-container:first-child > div.min-w-28:first-child .hulyButton').click() if (slot.dateStart === 'today') { await this.buttonCalendarToday().click() } else { @@ -204,21 +204,17 @@ export class PlanningPage extends CalendarPage { // timeStart const hours = slot.timeStart.substring(0, 2) const minutes = slot.timeStart.substring(2, slot.timeStart.length) + await row.locator('div.dateEditor-container:nth-child(1) .hulyButton span.digit:first-child').focus() await row - .locator('div.dateEditor-container:nth-child(1) button:last-child span.digit:first-child') - .click({ delay: 200 }) - await row - .locator('div.dateEditor-container:nth-child(1) button:last-child span.digit:first-child') + .locator('div.dateEditor-container:nth-child(1) .hulyButton span.digit:first-child') .pressSequentially(hours, { delay: 100 }) + await row.locator('div.dateEditor-container:nth-child(1) .hulyButton span.digit:last-child').focus() await row - .locator('div.dateEditor-container:nth-child(1) button:last-child span.digit:last-child') - .click({ delay: 200 }) - await row - .locator('div.dateEditor-container:nth-child(1) button:last-child span.digit:last-child') + .locator('div.dateEditor-container:nth-child(1) .hulyButton span.digit:last-child') .pressSequentially(minutes, { delay: 100 }) // dateEnd + timeEnd - await row.locator('div.dateEditor-container.difference button').click() + await row.locator('div.dateEditor-container.difference .hulyButton').click() await this.fillSelectDatePopup(slot.dateEnd.day, slot.dateEnd.month, slot.dateEnd.year, slot.timeEnd) } @@ -228,11 +224,13 @@ export class PlanningPage extends CalendarPage { : 'div.hulyModal-container div.slots-content div.scroller-container div.box div.flex-between.min-w-full' const row = this.page.locator(p).nth(rowNumber) // timeStart - await expect(row.locator('div.dateEditor-container:nth-child(1) button:last-child div.datetime-input')).toHaveText( - slot.timeStart - ) + await expect( + row.locator('div.dateEditor-container:nth-child(1) .hulyButton:last-child div.datetime-input') + ).toHaveText(slot.timeStart) // timeEnd - await expect(row.locator('div.dateEditor-container.difference button > div:first-child')).toHaveText(slot.timeEnd) + await expect(row.locator('div.dateEditor-container.difference .hulyButton > div:first-child')).toHaveText( + slot.timeEnd + ) } async openToDoByName (toDoName: string): Promise { @@ -304,11 +302,10 @@ export class PlanningPage extends CalendarPage { public async deleteTimeSlot (rowNumber: number): Promise { const row = this.page .locator( - 'div.hulyModal-container div.slots-content div.scroller-container div.box div.flex-between.min-w-full div.tool' + 'div.hulyModal-container div.slots-content div.scroller-container div.box div.flex-between.min-w-full button[data-id="btnDelete"]' ) .nth(rowNumber) - await row.locator('xpath=..').hover() - await row.locator('button').click() + await row.click() await this.pressYesDeletePopup(this.page) } @@ -317,8 +314,8 @@ export class PlanningPage extends CalendarPage { .locator('div.hulyModal-container div.slots-content div.scroller-container div.box div.flex-between.min-w-full') .nth(rowNumber) // dateEnd - await expect(row.locator('div.dateEditor-container:first-child > div.min-w-28:first-child button')).toContainText( - dateEnd - ) + await expect( + row.locator('div.dateEditor-container:first-child > div.min-w-28:first-child .hulyButton') + ).toContainText(dateEnd) } }