From b159c0610aaf4580764456c90a557bed6a646e70 Mon Sep 17 00:00:00 2001 From: utkaka Date: Tue, 22 Apr 2025 22:33:02 +0700 Subject: [PATCH] Uberf 10285 refactor header button (#8655) Signed-off-by: Anton Alexeyev --- models/recruit/src/index.ts | 38 ++-- .../ui/src/components/HeaderButton.svelte | 130 +++++++++++++ packages/ui/src/index.ts | 1 + packages/ui/src/types.ts | 17 +- .../src/components/NewDocumentHeader.svelte | 97 +++------ .../src/components/DriveSpaceHeader.svelte | 99 ++++------ .../src/components/NewItemsHeader.svelte | 33 ++-- .../src/components/NewCandidateHeader.svelte | 75 +++---- plugins/recruit/package.json | 3 +- plugins/recruit/src/index.ts | 4 + .../src/components/NewIssueHeader.svelte | 184 +++++++----------- .../tests/model/documents/documents-page.ts | 2 +- .../sanity/tests/model/tracker/issues-page.ts | 9 +- tests/sanity/tests/tracker/subissues.spec.ts | 2 +- tests/sanity/tests/tracker/tracker.spec.ts | 2 +- 15 files changed, 383 insertions(+), 313 deletions(-) create mode 100644 packages/ui/src/components/HeaderButton.svelte diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 962a09d5a9..4d842364b4 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -1018,24 +1018,28 @@ export function createModel (builder: Builder): void { }, override: [recruit.action.CreateGlobalApplication] }) - createAction(builder, { - action: view.actionImpl.ShowPopup, - actionProps: { - component: recruit.component.CreateCandidate, - element: 'top' + createAction( + builder, + { + action: view.actionImpl.ShowPopup, + actionProps: { + component: recruit.component.CreateCandidate, + element: 'top' + }, + label: recruit.string.CreateTalent, + icon: recruit.icon.Create, + keyBinding: ['keyC'], + input: 'none', + category: recruit.category.Recruit, + target: core.class.Doc, + context: { + mode: ['workbench', 'browser'], + application: recruit.app.Recruit, + group: 'create' + } }, - label: recruit.string.CreateTalent, - icon: recruit.icon.Create, - keyBinding: ['keyC'], - input: 'none', - category: recruit.category.Recruit, - target: core.class.Doc, - context: { - mode: ['workbench', 'browser'], - application: recruit.app.Recruit, - group: 'create' - } - }) + recruit.action.CreateTalent + ) createAction(builder, { action: view.actionImpl.ShowPopup, diff --git a/packages/ui/src/components/HeaderButton.svelte b/packages/ui/src/components/HeaderButton.svelte new file mode 100644 index 0000000000..facf6b8e67 --- /dev/null +++ b/packages/ui/src/components/HeaderButton.svelte @@ -0,0 +1,130 @@ + + + +{#await filterAllowedActions()} + +{:then filtered} + {#if mainAction !== undefined} + {#if loading} + + {:else} +
+ {#if items.length === 1} + + {:else} + { + items.find((a) => a.id === ev.detail)?.callback() + }} + on:click={mainAction.callback} + mainButtonId={mainAction.id !== null ? String(mainAction.id).replaceAll(':', '-') : undefined} + showTooltipMain={{ + direction: 'bottom', + label: mainAction.label, + keys: mainAction.keyBinding + }} + > +
+ {#if mainAction.draft === true} +
+ {/if} +
+ + {/if} +
+ {/if} + {/if} +{/await} + + diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index f4830d5fed..9a0224687f 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -54,6 +54,7 @@ export { getCurrentLocation, locationToUrl, navigate, location, setLocationStora export { default as EditBox } from './components/EditBox.svelte' export { default as Label } from './components/Label.svelte' export { default as Button } from './components/Button.svelte' +export { default as HeaderButton } from './components/HeaderButton.svelte' export { default as ButtonWithDropdown } from './components/ButtonWithDropdown.svelte' export { default as ButtonGroup } from './components/ButtonGroup.svelte' export { default as Status } from './components/Status.svelte' diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index 9b66828ae6..365722d620 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -import { type Timestamp } from '@hcengineering/core' +import { type AccountRole, type Permission, type Timestamp, type Ref, type TypedSpace } from '@hcengineering/core' import type { Asset, IntlString, @@ -510,6 +510,21 @@ export interface SelectPopupValueType { } } +/** + * @public + */ +export interface HeaderButtonAction extends SelectPopupValueType { + callback: () => void + keyBindingPromise?: Promise + keyBinding?: string[] | undefined + draft?: boolean + accountRole?: AccountRole + permission?: { + id: Ref + space: Ref + } +} + /** * @public */ diff --git a/plugins/document-resources/src/components/NewDocumentHeader.svelte b/plugins/document-resources/src/components/NewDocumentHeader.svelte index 074aaff44b..2c6c31fd85 100644 --- a/plugins/document-resources/src/components/NewDocumentHeader.svelte +++ b/plugins/document-resources/src/components/NewDocumentHeader.svelte @@ -13,17 +13,9 @@ // limitations under the License. --> -{#if loading} - -{:else if hasAccountRole(getCurrentAccount(), AccountRole.User) || hasTeamspace} -
- {#if hasAccountRole(getCurrentAccount(), AccountRole.User)} - {#if hasTeamspace} - { - void dropdownItemSelected(ev.detail) - }} - /> - {:else} -
-{/if} + diff --git a/plugins/drive-resources/src/components/DriveSpaceHeader.svelte b/plugins/drive-resources/src/components/DriveSpaceHeader.svelte index d2eb8b9bb9..0c580ae055 100644 --- a/plugins/drive-resources/src/components/DriveSpaceHeader.svelte +++ b/plugins/drive-resources/src/components/DriveSpaceHeader.svelte @@ -13,15 +13,14 @@ // limitations under the License. --> -{#if loading} - -{:else} -
- {#if hasDrive} - { - void handleDropdownItemSelected(ev.detail) - }} - /> - {:else} -
-{/if} + diff --git a/plugins/lead-resources/src/components/NewItemsHeader.svelte b/plugins/lead-resources/src/components/NewItemsHeader.svelte index 3ae8e391f8..3b9354347e 100644 --- a/plugins/lead-resources/src/components/NewItemsHeader.svelte +++ b/plugins/lead-resources/src/components/NewItemsHeader.svelte @@ -13,26 +13,29 @@ // limitations under the License. --> -{#if hasAccountRole(getCurrentAccount(), AccountRole.User)} -
-
-{/if} + diff --git a/plugins/recruit-resources/src/components/NewCandidateHeader.svelte b/plugins/recruit-resources/src/components/NewCandidateHeader.svelte index 5d906540f6..974137c848 100644 --- a/plugins/recruit-resources/src/components/NewCandidateHeader.svelte +++ b/plugins/recruit-resources/src/components/NewCandidateHeader.svelte @@ -14,17 +14,23 @@ --> -{#if hasAccountRole(getCurrentAccount(), AccountRole.User)} -
- -
-{/if} - - + diff --git a/plugins/recruit/package.json b/plugins/recruit/package.json index bccc3c07a8..5505ef08e8 100644 --- a/plugins/recruit/package.json +++ b/plugins/recruit/package.json @@ -45,7 +45,8 @@ "@hcengineering/task": "^0.6.20", "@hcengineering/calendar": "^0.6.24", "@hcengineering/ui": "^0.6.15", - "@hcengineering/tags": "^0.6.16" + "@hcengineering/tags": "^0.6.16", + "@hcengineering/view": "^0.6.13" }, "repository": "https://github.com/hcengineering/platform", "publishConfig": { diff --git a/plugins/recruit/src/index.ts b/plugins/recruit/src/index.ts index ca2f008e06..a9d927a4cd 100644 --- a/plugins/recruit/src/index.ts +++ b/plugins/recruit/src/index.ts @@ -19,6 +19,7 @@ import { plugin } from '@hcengineering/platform' import type { ProjectTypeDescriptor, TaskType } from '@hcengineering/task' import { AnyComponent, Location, ResolvedLocation } from '@hcengineering/ui' import type { Applicant, ApplicantMatch, Candidate, Opinion, Review, Vacancy, VacancyList } from './types' +import { Action } from '@hcengineering/view' export * from './types' export * from './analytics' @@ -45,6 +46,9 @@ const recruit = plugin(recruitId, { descriptors: { VacancyType: '' as Ref }, + action: { + CreateTalent: '' as Ref> + }, mixin: { Candidate: '' as Ref>, VacancyList: '' as Ref>, diff --git a/plugins/tracker-resources/src/components/NewIssueHeader.svelte b/plugins/tracker-resources/src/components/NewIssueHeader.svelte index b0da495e00..9818442422 100644 --- a/plugins/tracker-resources/src/components/NewIssueHeader.svelte +++ b/plugins/tracker-resources/src/components/NewIssueHeader.svelte @@ -14,17 +14,10 @@ --> -
- {#if projectExists} - { - dropdownItemSelected(ev.detail) - }} - mainButtonId={'new-issue'} - showTooltipMain={{ - direction: 'bottom', - label, - keys - }} - > -
- {#if draftExists} -
- {/if} -
- - {:else} -
- - + diff --git a/tests/sanity/tests/model/documents/documents-page.ts b/tests/sanity/tests/model/documents/documents-page.ts index 56cf3819dd..c6ca2a5dd7 100644 --- a/tests/sanity/tests/model/documents/documents-page.ts +++ b/tests/sanity/tests/model/documents/documents-page.ts @@ -18,7 +18,7 @@ export class DocumentsPage extends CommonPage { readonly popupMoveDocument: DocumentMovePopup readonly buttonCreateDocument = (): Locator => - this.page.locator('div[data-float="navigator"] button[id="new-document"]') + this.page.locator('div[data-float="navigator"] button[id="document-string-CreateDocument"]') readonly buttonDocumentWrapper = (name: string): Locator => this.page.locator(`button.hulyNavItem-container:has-text("${name}")`) diff --git a/tests/sanity/tests/model/tracker/issues-page.ts b/tests/sanity/tests/model/tracker/issues-page.ts index 6a2b87ebcc..1defbf96f4 100644 --- a/tests/sanity/tests/model/tracker/issues-page.ts +++ b/tests/sanity/tests/model/tracker/issues-page.ts @@ -10,7 +10,8 @@ export class IssuesPage extends CommonTrackerPage { modelSelectorAll = (): Locator => this.page.locator('label[data-id="tab-all"]') issues = (): Locator => this.page.locator('.antiPanel-navigator').locator('text="Issues"') subIssues = (): Locator => this.page.locator('button:has-text("Add sub-issue")') - newIssue = (): Locator => this.page.locator('#new-issue') + newIssue = (): Locator => this.page.locator('#tracker-string-NewIssue') + resumeDraft = (): Locator => this.page.locator('#tracker-string-ResumeDraft') modelSelectorActive = (): Locator => this.page.locator('label[data-id="tab-active"]') modelSelectorBacklog = (): Locator => this.page.locator('label[data-id="tab-backlog"]') buttonCreateNewIssue = (): Locator => this.page.locator('button > div', { hasText: 'New issue' }) @@ -156,7 +157,7 @@ export class IssuesPage extends CommonTrackerPage { estimationSpan = (): Locator => this.page.locator('.estimation-container >> span').first() okButton = (): Locator => this.page.getByRole('button', { name: 'Ok', exact: true }) - newIssueButton = (): Locator => this.page.locator('#new-issue') + newIssueButton = (): Locator => this.page.locator('#tracker-string-NewIssue') issueNameInput = (): Locator => this.page.locator('#issue-name >> input') issueDescriptionInput = (): Locator => this.page.locator('#issue-description >> [contenteditable]') statusEditor = (): Locator => this.page.locator('#status-editor') @@ -232,6 +233,10 @@ export class IssuesPage extends CommonTrackerPage { await this.newIssue().click() } + async clickOnResumeDraft (): Promise { + await this.resumeDraft().click() + } + async navigateToMyIssues (): Promise { await this.myIssuesButton().click() } diff --git a/tests/sanity/tests/tracker/subissues.spec.ts b/tests/sanity/tests/tracker/subissues.spec.ts index 37e2044a5d..fd27b298bc 100644 --- a/tests/sanity/tests/tracker/subissues.spec.ts +++ b/tests/sanity/tests/tracker/subissues.spec.ts @@ -45,7 +45,7 @@ test.describe('Tracker sub-issues tests', () => { await fillIssueForm(page, props) await page.keyboard.press('Escape') await page.keyboard.press('Escape') - await issuesPage.clickOnNewIssue() + await issuesPage.clickOnResumeDraft() await checkIssueDraft(page, props) }) diff --git a/tests/sanity/tests/tracker/tracker.spec.ts b/tests/sanity/tests/tracker/tracker.spec.ts index b119b24fab..2b095cf78b 100644 --- a/tests/sanity/tests/tracker/tracker.spec.ts +++ b/tests/sanity/tests/tracker/tracker.spec.ts @@ -161,7 +161,7 @@ test.describe('Tracker tests', () => { await issuesPage.inputTextPlaceholderFill('1') await issuesPage.setDueDate('24') await issuesPage.pressEscapeTwice() - await issuesPage.clickOnNewIssue() + await issuesPage.clickOnResumeDraft() await checkIssueDraft(page, { name: issueName, description: issueName,