mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-31 12:19:47 +02:00
247 lines
7.1 KiB
Svelte
247 lines
7.1 KiB
Svelte
<!--
|
|
// Copyright © 2022-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 core from '@hcengineering/core'
|
|
import {
|
|
Breadcrumb,
|
|
Header,
|
|
Scroller,
|
|
EditBox,
|
|
Spinner,
|
|
Button,
|
|
IconEdit,
|
|
IconClose,
|
|
IconCheckmark,
|
|
IconDelete,
|
|
Label,
|
|
navigate,
|
|
showPopup,
|
|
DropdownLabels,
|
|
deviceOptionsStore as deviceInfo,
|
|
themeStore,
|
|
getWeekDayNames,
|
|
getLocalWeekStart,
|
|
hasLocalWeekStart,
|
|
type DropdownTextItem
|
|
} from '@hcengineering/ui'
|
|
import { loginId } from '@hcengineering/login'
|
|
import { EditableAvatar } from '@hcengineering/contact-resources'
|
|
import { translateCB } from '@hcengineering/platform'
|
|
import { getClient, MessageBox } from '@hcengineering/presentation'
|
|
import { WorkspaceSetting } from '@hcengineering/setting'
|
|
import { AvatarType } from '@hcengineering/contact'
|
|
|
|
import setting from '../plugin'
|
|
import { getAccountClient } from '../utils'
|
|
|
|
let loading = true
|
|
let isEditingName = false
|
|
let oldName: string
|
|
let name: string = ''
|
|
|
|
const accountClient = getAccountClient()
|
|
const disabledSet = ['\n', '<', '>', '/', '\\']
|
|
|
|
$: editNameDisabled =
|
|
isEditingName &&
|
|
(name.trim().length > 40 ||
|
|
name.trim() === oldName ||
|
|
name.trim() === '' ||
|
|
disabledSet.some((it) => name.includes(it)))
|
|
|
|
void loadWorkspaceName()
|
|
|
|
async function loadWorkspaceName (): Promise<void> {
|
|
const res = await accountClient.getWorkspaceInfo()
|
|
|
|
oldName = res.name
|
|
name = oldName
|
|
loading = false
|
|
}
|
|
|
|
async function handleEditName (): Promise<void> {
|
|
if (editNameDisabled) {
|
|
return
|
|
}
|
|
|
|
if (isEditingName) {
|
|
await accountClient.updateWorkspaceName(name.trim())
|
|
}
|
|
|
|
isEditingName = !isEditingName
|
|
}
|
|
|
|
function handleCancelEditName (): void {
|
|
name = oldName
|
|
isEditingName = false
|
|
}
|
|
|
|
async function handleDelete (): Promise<void> {
|
|
showPopup(MessageBox, {
|
|
label: setting.string.DeleteWorkspace,
|
|
message: setting.string.DeleteWorkspaceConfirm,
|
|
dangerous: true,
|
|
action: async () => {
|
|
await accountClient.deleteWorkspace()
|
|
navigate({ path: [loginId] })
|
|
}
|
|
})
|
|
}
|
|
|
|
// Avatar
|
|
let avatarEditor: EditableAvatar
|
|
let workspaceSettings: WorkspaceSetting | undefined = undefined
|
|
|
|
const client = getClient()
|
|
void client.findOne(setting.class.WorkspaceSetting, {}).then((r) => {
|
|
workspaceSettings = r
|
|
})
|
|
|
|
async function handleAvatarDone (): Promise<void> {
|
|
if (workspaceSettings === undefined) {
|
|
const avatar = await avatarEditor.createAvatar()
|
|
await client.createDoc(
|
|
setting.class.WorkspaceSetting,
|
|
core.space.Workspace,
|
|
{ icon: avatar.avatar },
|
|
setting.ids.WorkspaceSetting
|
|
)
|
|
return
|
|
}
|
|
|
|
const avatar = await avatarEditor.createAvatar()
|
|
if (workspaceSettings.icon != null && workspaceSettings.icon !== avatar.avatar) {
|
|
// Different avatar
|
|
await avatarEditor.removeAvatar(workspaceSettings.icon)
|
|
}
|
|
await client.update(workspaceSettings, {
|
|
icon: avatar.avatar
|
|
})
|
|
}
|
|
|
|
const weekInfoFirstDay: number = getLocalWeekStart()
|
|
const hasWeekInfo: boolean = hasLocalWeekStart()
|
|
const weekNames = getWeekDayNames()
|
|
let items: DropdownTextItem[] = []
|
|
let selected: string
|
|
|
|
$: translateCB(
|
|
hasWeekInfo ? setting.string.SystemSetupString : setting.string.DefaultString,
|
|
{ day: weekNames?.get(weekInfoFirstDay)?.toLowerCase() ?? '' },
|
|
$themeStore.language,
|
|
(r) => {
|
|
items = [
|
|
{ id: 'system', label: r },
|
|
...Array.from(weekNames.entries()).map((it) => ({ id: it[0].toString(), label: it[1] }))
|
|
]
|
|
const savedFirstDayOfWeek = localStorage.getItem('firstDayOfWeek') ?? 'system'
|
|
selected = items[savedFirstDayOfWeek === 'system' ? 0 : $deviceInfo.firstDayOfWeek + 1].id
|
|
}
|
|
)
|
|
const onSelected = (e: CustomEvent<string>): void => {
|
|
selected = e.detail
|
|
localStorage.setItem('firstDayOfWeek', `${e.detail}`)
|
|
$deviceInfo.firstDayOfWeek = e.detail === 'system' ? weekInfoFirstDay : parseInt(e.detail, 10) ?? 1
|
|
}
|
|
</script>
|
|
|
|
<div class="hulyComponent">
|
|
<Header adaptive={'disabled'}>
|
|
<Breadcrumb icon={setting.icon.Setting} label={setting.string.General} size={'large'} isCurrent />
|
|
</Header>
|
|
<div class="hulyComponent-content__column content">
|
|
{#if loading}
|
|
<Spinner size={'small'} />
|
|
{:else}
|
|
<Scroller align={'center'} padding={'var(--spacing-3)'} bottomPadding={'var(--spacing-3)'}>
|
|
<div class="hulyComponent-content flex-col flex-gap-4">
|
|
<div class="title"><Label label={setting.string.Workspace} /></div>
|
|
<div class="ws">
|
|
<EditableAvatar
|
|
person={{
|
|
avatarType: AvatarType.IMAGE,
|
|
avatar: workspaceSettings?.icon
|
|
}}
|
|
size="medium"
|
|
bind:this={avatarEditor}
|
|
on:done={handleAvatarDone}
|
|
imageOnly
|
|
lessCrop
|
|
/>
|
|
<div class="editBox">
|
|
<EditBox
|
|
bind:value={name}
|
|
placeholder={setting.string.WorkspaceName}
|
|
kind="ghost-large"
|
|
disabled={!isEditingName}
|
|
/>
|
|
</div>
|
|
<Button
|
|
icon={isEditingName ? IconCheckmark : IconEdit}
|
|
kind="ghost"
|
|
size="small"
|
|
disabled={editNameDisabled}
|
|
on:click={handleEditName}
|
|
/>
|
|
{#if isEditingName}
|
|
<Button icon={IconClose} kind="ghost" size="small" on:click={handleCancelEditName} />
|
|
{/if}
|
|
<Button
|
|
icon={IconDelete}
|
|
kind="dangerous"
|
|
on:click={handleDelete}
|
|
showTooltip={{ label: setting.string.DeleteWorkspace }}
|
|
/>
|
|
</div>
|
|
<div class="flex-col flex-gap-4 mt-6">
|
|
<div class="title"><Label label={setting.string.Calendar} /></div>
|
|
<div class="flex-row-center flex-gap-4">
|
|
<Label label={setting.string.StartOfTheWeek} />
|
|
<DropdownLabels
|
|
{items}
|
|
kind={'regular'}
|
|
size={'medium'}
|
|
{selected}
|
|
enableSearch={false}
|
|
on:selected={onSelected}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Scroller>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
.title {
|
|
font-weight: 500;
|
|
font-size: 1rem;
|
|
}
|
|
.ws {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.editBox {
|
|
width: 16rem;
|
|
}
|
|
|
|
.delete {
|
|
width: 6rem;
|
|
}
|
|
</style>
|