TSK-1682: Introduced reusable SectionEmpty for numerous existing and upcoming cases (#5220)

Signed-off-by: Petr Vyazovetskiy <develop.pit@gmail.com>
This commit is contained in:
Pete Anøther 2024-04-08 02:54:04 -03:00 committed by GitHub
parent 52908e051c
commit a3a77eb6b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 73 additions and 53 deletions

View File

@ -12,6 +12,7 @@
"CompanyCreateLabel": "Company", "CompanyCreateLabel": "Company",
"VacancyPlaceholder": "Software Engineer", "VacancyPlaceholder": "Software Engineer",
"CreateAnApplication": "New Application", "CreateAnApplication": "New Application",
"NoVacancies": "No Vacancies",
"NoApplicationsForTalent": "There are no applications for this talent.", "NoApplicationsForTalent": "There are no applications for this talent.",
"NoApplicationsForVacancy": "There are no applications for this vacancy.", "NoApplicationsForVacancy": "There are no applications for this vacancy.",
"CreateApplication": "New Application", "CreateApplication": "New Application",
@ -128,4 +129,4 @@
"TalentRequired": "Please select talent", "TalentRequired": "Please select talent",
"VacancyRequired": "Please select vacancy" "VacancyRequired": "Please select vacancy"
} }
} }

View File

@ -12,6 +12,7 @@
"CompanyCreateLabel": "Empresa", "CompanyCreateLabel": "Empresa",
"VacancyPlaceholder": "Ingeniero de software", "VacancyPlaceholder": "Ingeniero de software",
"CreateAnApplication": "Nueva solicitud", "CreateAnApplication": "Nueva solicitud",
"NoVacancies": "No hay vacantes",
"NoApplicationsForTalent": "No hay solicitudes para este talento.", "NoApplicationsForTalent": "No hay solicitudes para este talento.",
"NoApplicationsForVacancy": "No hay solicitudes para esta vacante.", "NoApplicationsForVacancy": "No hay solicitudes para esta vacante.",
"CreateApplication": "Nueva solicitud", "CreateApplication": "Nueva solicitud",
@ -125,4 +126,4 @@
"TalentRequired": "Seleccione un talento", "TalentRequired": "Seleccione un talento",
"VacancyRequired": "Seleccione una vacante" "VacancyRequired": "Seleccione una vacante"
} }
} }

View File

@ -12,6 +12,7 @@
"CompanyCreateLabel": "Empresa", "CompanyCreateLabel": "Empresa",
"VacancyPlaceholder": "Engenheiro de software", "VacancyPlaceholder": "Engenheiro de software",
"CreateAnApplication": "Nova candidatura", "CreateAnApplication": "Nova candidatura",
"NoVacancies": "Não existem vagas",
"NoApplicationsForTalent": "Não existem candidaturas para este talento.", "NoApplicationsForTalent": "Não existem candidaturas para este talento.",
"NoApplicationsForVacancy": "Não existem candidaturas para esta vaga.", "NoApplicationsForVacancy": "Não existem candidaturas para esta vaga.",
"CreateApplication": "Nova candidatura", "CreateApplication": "Nova candidatura",
@ -125,4 +126,4 @@
"TalentRequired": "Selecione um talento", "TalentRequired": "Selecione um talento",
"VacancyRequired": "Selecione uma vaga" "VacancyRequired": "Selecione uma vaga"
} }
} }

View File

@ -12,6 +12,7 @@
"CompanyCreateLabel": "Компания", "CompanyCreateLabel": "Компания",
"VacancyPlaceholder": "Разработчик", "VacancyPlaceholder": "Разработчик",
"CreateAnApplication": "Новый Кандидат", "CreateAnApplication": "Новый Кандидат",
"NoVacancies": "Нет вакансий",
"NoApplicationsForTalent": "Нет кандидатов для данного таланта.", "NoApplicationsForTalent": "Нет кандидатов для данного таланта.",
"NoApplicationsForVacancy": "Нет кандидатов для данной вакансии.", "NoApplicationsForVacancy": "Нет кандидатов для данной вакансии.",
"CreateApplication": "Новый Кандидат", "CreateApplication": "Новый Кандидат",
@ -59,7 +60,7 @@
"ManageVacancyStatuses": "Управление типами вакансии", "ManageVacancyStatuses": "Управление типами вакансии",
"EditVacancy": "Редактировать", "EditVacancy": "Редактировать",
"FullDescription": "Детальное описание", "FullDescription": "Детальное описание",
"CreateReview": "Запланировать Ревью", "CreateReview": "Запланировать Ревью",
"CreateReviewParams": "Запланировать {label}", "CreateReviewParams": "Запланировать {label}",
"Reviews": "Ревью", "Reviews": "Ревью",
@ -128,4 +129,4 @@
"TalentRequired": "Пожалуйста, выберите таланта", "TalentRequired": "Пожалуйста, выберите таланта",
"VacancyRequired": "Пожалуйста, выберите вакансию" "VacancyRequired": "Пожалуйста, выберите вакансию"
} }
} }

View File

@ -21,6 +21,7 @@
import CreateApplication from './CreateApplication.svelte' import CreateApplication from './CreateApplication.svelte'
import IconApplication from './icons/Application.svelte' import IconApplication from './icons/Application.svelte'
import FileDuo from './icons/FileDuo.svelte' import FileDuo from './icons/FileDuo.svelte'
import SectionEmpty from './SectionEmpty.svelte'
export let objectId: Ref<Doc> export let objectId: Ref<Doc>
@ -50,7 +51,7 @@
</svelte:fragment> </svelte:fragment>
<svelte:fragment slot="content"> <svelte:fragment slot="content">
{#if applications > 0 && viewlet && !loading} {#if applications > 0 && viewlet !== undefined && !loading}
<Scroller horizontal> <Scroller horizontal>
<Table <Table
_class={recruit.class.Applicant} _class={recruit.class.Applicant}
@ -60,19 +61,13 @@
/> />
</Scroller> </Scroller>
{:else} {:else}
<div class="antiSection-empty solid flex-col-center mt-3"> <SectionEmpty icon={FileDuo} label={recruit.string.NoApplicationsForTalent}>
<div class="caption-color">
<FileDuo size={'large'} />
</div>
<span class="content-dark-color">
<Label label={recruit.string.NoApplicationsForTalent} />
</span>
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<span class="over-underline content-color" on:click={createApp}> <span class="over-underline content-color" on:click={createApp}>
<Label label={recruit.string.CreateAnApplication} /> <Label label={recruit.string.CreateAnApplication} />
</span> </span>
</div> </SectionEmpty>
{/if} {/if}
</svelte:fragment> </svelte:fragment>
</Section> </Section>

View File

@ -0,0 +1,36 @@
<!--
//
// Copyright © 2024 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 type { IntlString } from '@hcengineering/platform'
import { Icon, Label } from '@hcengineering/ui'
import type { ComponentProps } from 'svelte'
export let icon: ComponentProps<Icon>['icon']
export let label: IntlString
export let labelParams: Record<string, any> = {}
</script>
<div class="antiSection-empty solid flex-col-center mt-3">
<div class="flex-center caption-color">
<Icon {icon} size="large" />
</div>
<span class="text-sm content-dark-color mt-2">
<Label {label} params={labelParams} />
</span>
<slot />
</div>

View File

@ -23,6 +23,7 @@
import CreateApplication from './CreateApplication.svelte' import CreateApplication from './CreateApplication.svelte'
import IconApplication from './icons/Application.svelte' import IconApplication from './icons/Application.svelte'
import FileDuo from './icons/FileDuo.svelte' import FileDuo from './icons/FileDuo.svelte'
import SectionEmpty from './SectionEmpty.svelte'
export let objectId: Ref<Vacancy> export let objectId: Ref<Vacancy>
let applications: number let applications: number
@ -63,7 +64,7 @@
</div> </div>
</div> </div>
{#if applications > 0} {#if applications > 0}
{#if viewlet && !loading} {#if viewlet !== undefined && !loading}
<Scroller horizontal> <Scroller horizontal>
<Table <Table
_class={recruit.class.Applicant} _class={recruit.class.Applicant}
@ -76,16 +77,12 @@
<Loading /> <Loading />
{/if} {/if}
{:else} {:else}
<div class="antiSection-empty solid flex-col-center mt-3"> <SectionEmpty icon={FileDuo} label={recruit.string.NoApplicationsForVacancy}>
<div class="caption-color"> <!-- svelte-ignore a11y-click-events-have-key-events -->
<FileDuo size={'large'} /> <!-- svelte-ignore a11y-no-static-element-interactions -->
</div>
<span class="content-dark-color">
<Label label={recruit.string.NoApplicationsForVacancy} />
</span>
<span class="over-underline content-color" on:click={createApp}> <span class="over-underline content-color" on:click={createApp}>
<Label label={recruit.string.CreateAnApplication} /> <Label label={recruit.string.CreateAnApplication} />
</span> </span>
</div> </SectionEmpty>
{/if} {/if}
</div> </div>

View File

@ -14,7 +14,6 @@
--> -->
<script lang="ts"> <script lang="ts">
import { Doc, Ref } from '@hcengineering/core' import { Doc, Ref } from '@hcengineering/core'
import { getEmbeddedLabel } from '@hcengineering/platform'
import presentation from '@hcengineering/presentation' import presentation from '@hcengineering/presentation'
import { Button, Icon, IconAdd, Label, showPopup, Scroller } from '@hcengineering/ui' import { Button, Icon, IconAdd, Label, showPopup, Scroller } from '@hcengineering/ui'
import view, { BuildModelKey } from '@hcengineering/view' import view, { BuildModelKey } from '@hcengineering/view'
@ -22,6 +21,7 @@
import recruit from '../plugin' import recruit from '../plugin'
import CreateVacancy from './CreateVacancy.svelte' import CreateVacancy from './CreateVacancy.svelte'
import FileDuo from './icons/FileDuo.svelte' import FileDuo from './icons/FileDuo.svelte'
import SectionEmpty from './SectionEmpty.svelte'
export let objectId: Ref<Doc> export let objectId: Ref<Doc>
export let vacancies: number | undefined export let vacancies: number | undefined
@ -71,18 +71,12 @@
/> />
</Scroller> </Scroller>
{:else} {:else}
<div class="antiSection-empty solid flex-col-center mt-3"> <SectionEmpty icon={FileDuo} label={recruit.string.NoVacancies}>
<div class="caption-color"> <!-- svelte-ignore a11y-click-events-have-key-events -->
<FileDuo size={'large'} /> <!-- svelte-ignore a11y-no-static-element-interactions -->
</div> <span class="over-underline content-color" on:click={createApp}>
<span class="content-dark-color"> <Label label={recruit.string.CreateVacancy} />
<Label label={getEmbeddedLabel('No Vacancies')} />
</span> </span>
{#if !readonly} </SectionEmpty>
<span class="over-underline content-color" on:click={createApp}>
<Label label={recruit.string.CreateVacancy} />
</span>
{/if}
</div>
{/if} {/if}
</div> </div>

View File

@ -18,6 +18,7 @@
import { Table } from '@hcengineering/view-resources' import { Table } from '@hcengineering/view-resources'
import recruit from '../../plugin' import recruit from '../../plugin'
import FileDuo from '../icons/FileDuo.svelte' import FileDuo from '../icons/FileDuo.svelte'
import SectionEmpty from '../SectionEmpty.svelte'
import CreateOpinion from './CreateOpinion.svelte' import CreateOpinion from './CreateOpinion.svelte'
export let objectId: Ref<Doc> export let objectId: Ref<Doc>
@ -44,16 +45,12 @@
loadingProps={{ length: opinions }} loadingProps={{ length: opinions }}
/> />
{:else} {:else}
<div class="antiSection-empty solid flex-col-center mt-3"> <SectionEmpty icon={FileDuo} label={recruit.string.NoReviewForCandidate}>
<div class="content-color"> <!-- svelte-ignore a11y-click-events-have-key-events -->
<FileDuo size={'large'} /> <!-- svelte-ignore a11y-no-static-element-interactions -->
</div>
<div class="text-sm content-dark-color mt-2">
<Label label={recruit.string.NoReviewForCandidate} />
</div>
<span class="text-sm content-color over-underline" on:click={createApp}> <span class="text-sm content-color over-underline" on:click={createApp}>
<Label label={recruit.string.CreateAnReview} /> <Label label={recruit.string.CreateAnReview} />
</span> </span>
</div> </SectionEmpty>
{/if} {/if}
</div> </div>

View File

@ -22,6 +22,7 @@
import { Table } from '@hcengineering/view-resources' import { Table } from '@hcengineering/view-resources'
import recruit from '../../plugin' import recruit from '../../plugin'
import FileDuo from '../icons/FileDuo.svelte' import FileDuo from '../icons/FileDuo.svelte'
import SectionEmpty from '../SectionEmpty.svelte'
import CreateReview from './CreateReview.svelte' import CreateReview from './CreateReview.svelte'
export let objectId: Ref<Doc> export let objectId: Ref<Doc>
@ -93,19 +94,14 @@
/> />
</Scroller> </Scroller>
{:else} {:else}
<div class="antiSection-empty solid flex-col-center mt-3"> <SectionEmpty icon={FileDuo} label={recruit.string.NoReviewForCandidate}>
<div class="caption-color">
<FileDuo size={'large'} />
</div>
<span class="content-dark-color mt-2">
<Label label={recruit.string.NoReviewForCandidate} />
</span>
{#if !readonly} {#if !readonly}
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<span class="over-underline content-color" on:click={createApp}> <span class="over-underline content-color" on:click={createApp}>
<Label label={recruit.string.CreateAnReview} /> <Label label={recruit.string.CreateAnReview} />
</span> </span>
{/if} {/if}
</div> </SectionEmpty>
{/if} {/if}
</div> </div>

View File

@ -39,6 +39,7 @@ export default mergeIds(recruitId, recruit, {
VacancyDescription: '' as IntlString, VacancyDescription: '' as IntlString,
CandidatesDescription: '' as IntlString, CandidatesDescription: '' as IntlString,
CreateAnApplication: '' as IntlString, CreateAnApplication: '' as IntlString,
NoVacancies: '' as IntlString,
NoApplicationsForTalent: '' as IntlString, NoApplicationsForTalent: '' as IntlString,
NoApplicationsForVacancy: '' as IntlString, NoApplicationsForVacancy: '' as IntlString,
FirstName: '' as IntlString, FirstName: '' as IntlString,

View File

@ -16,7 +16,7 @@
{#if $configurationStore.has(trackerId)} {#if $configurationStore.has(trackerId)}
<QueryIssuesList {object} {query} createParams={{ relatedTo: object }} hasSubIssues> <QueryIssuesList {object} {query} createParams={{ relatedTo: object }} hasSubIssues>
<svelte:fragment slot="header"> <svelte:fragment slot="header">
<div class="flex-row-center mb-3"> <div class="flex-row-center">
<div class="antiSection-header__icon"> <div class="antiSection-header__icon">
<Icon icon={tracker.icon.Issue} size={'small'} /> <Icon icon={tracker.icon.Issue} size={'small'} />
</div> </div>