mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-12 20:57:45 +02:00
fix: restructure workspace general settings (#10120)
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
@@ -19,9 +19,10 @@
|
||||
import type { Ref } from '@hcengineering/core'
|
||||
import { Blob as PlatformBlob } from '@hcengineering/core'
|
||||
import { Asset } from '@hcengineering/platform'
|
||||
import presentation, { Card, getFileUrl } from '@hcengineering/presentation'
|
||||
import {
|
||||
import presentation, { Card, getFileUrl, uiContext } from '@hcengineering/presentation'
|
||||
import ui, {
|
||||
AnySvelteComponent,
|
||||
Button,
|
||||
ColorDefinition,
|
||||
Label,
|
||||
TabList,
|
||||
@@ -171,6 +172,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
function handleClearClick (): void {
|
||||
selectedAvatar = undefined
|
||||
selectedAvatarType = AvatarType.COLOR
|
||||
selectedAvatarProps = { color: getPlatformAvatarColorForTextDef(name ?? '', $themeStore.dark).name }
|
||||
}
|
||||
|
||||
const showColorPopup = (event: MouseEvent) => {
|
||||
showPopup(
|
||||
ColorsPopup,
|
||||
@@ -238,6 +245,9 @@
|
||||
on:select={handleDropdownSelection}
|
||||
/>
|
||||
</div>
|
||||
<svelte:fragment slot="buttons">
|
||||
<Button minWidth={'5rem'} label={ui.string.Clear} kind={'ghost'} size={'large'} on:click={handleClearClick} />
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="footer">
|
||||
{#if selectedAvatarType === AvatarType.GRAVATAR}
|
||||
<div class="flex-col">
|
||||
|
||||
@@ -197,6 +197,11 @@
|
||||
"IntegrationIsUnstable": "Integrační služba má problémy. Některé funkce nemusí fungovat správně.",
|
||||
"MinValue": "Minimální hodnota",
|
||||
"MaxValue": "Maximální hodnota",
|
||||
"IntegerOnly": "Pouze celá čísla"
|
||||
"IntegerOnly": "Pouze celá čísla",
|
||||
"AccessControl": "Řízení přístupu",
|
||||
"DangerZone": "Nebezpečná zóna",
|
||||
"ApiAccess": "Přístup k API",
|
||||
"ApiToken": "API token",
|
||||
"GenerateApiToken": "Vygenerovat API token"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"IntegrationIsUnstable": "Der Integrationsdienst hat Probleme. Einige Funktionen funktionieren möglicherweise nicht richtig.",
|
||||
"MinValue": "Minimalwert",
|
||||
"MaxValue": "Maximalwert",
|
||||
"IntegerOnly": "Nur ganze Zahlen"
|
||||
"IntegerOnly": "Nur ganze Zahlen",
|
||||
"AccessControl": "Zugriffskontrolle",
|
||||
"DangerZone": "Gefahrenzone",
|
||||
"ApiAccess": "API-Zugriff",
|
||||
"ApiToken": "API-Token",
|
||||
"GenerateApiToken": "API-Token generieren"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"IntegrationIsUnstable": "Integration service is experiencing issues. Some features may not work properly.",
|
||||
"MinValue": "Minimum value",
|
||||
"MaxValue": "Maximum value",
|
||||
"IntegerOnly": "Integer numbers only"
|
||||
"IntegerOnly": "Integer numbers only",
|
||||
"AccessControl": "Access control",
|
||||
"DangerZone": "Danger zone",
|
||||
"ApiAccess": "API access",
|
||||
"ApiToken": "API token",
|
||||
"GenerateApiToken": "Generate API token"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +190,11 @@
|
||||
"IntegrationIsUnstable": "El servicio de integración está experimentando problemas. Es posible que algunas funciones no funcionen correctamente.",
|
||||
"MinValue": "Valor mínimo",
|
||||
"MaxValue": "Valor máximo",
|
||||
"IntegerOnly": "Solo números enteros"
|
||||
"IntegerOnly": "Solo números enteros",
|
||||
"AccessControl": "Control de acceso",
|
||||
"DangerZone": "Zona de peligro",
|
||||
"ApiAccess": "Acceso API",
|
||||
"ApiToken": "Token API",
|
||||
"GenerateApiToken": "Generar token API"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"IntegrationIsUnstable": "Le service d'intégration rencontre des problèmes. Certaines fonctionnalités peuvent ne pas fonctionner correctement.",
|
||||
"MinValue": "Valeur minimale",
|
||||
"MaxValue": "Valeur maximale",
|
||||
"IntegerOnly": "Nombres entiers uniquement"
|
||||
"IntegerOnly": "Nombres entiers uniquement",
|
||||
"AccessControl": "Contrôle d'accès",
|
||||
"DangerZone": "Zone dangereuse",
|
||||
"ApiAccess": "Accès API",
|
||||
"ApiToken": "Token API",
|
||||
"GenerateApiToken": "Générer un token API"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"IntegrationIsUnstable": "L'integrazione è instabile. Alcune funzionalità potrebbero non funzionare correttamente.",
|
||||
"MinValue": "Valore minimo",
|
||||
"MaxValue": "Valore massimo",
|
||||
"IntegerOnly": "Solo numeri interi"
|
||||
"IntegerOnly": "Solo numeri interi",
|
||||
"AccessControl": "Controllo accessi",
|
||||
"DangerZone": "Zona pericolosa",
|
||||
"ApiAccess": "Accesso API",
|
||||
"ApiToken": "Token API",
|
||||
"GenerateApiToken": "Genera token API"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"IntegrationIsUnstable": "統合サービスに問題が発生しています。一部の機能が正しく動作しない可能性があります。",
|
||||
"MinValue": "最小値",
|
||||
"MaxValue": "最大値",
|
||||
"IntegerOnly": "整数のみ"
|
||||
"IntegerOnly": "整数のみ",
|
||||
"AccessControl": "アクセス制御",
|
||||
"DangerZone": "危険ゾーン",
|
||||
"ApiAccess": "APIアクセス",
|
||||
"ApiToken": "APIトークン",
|
||||
"GenerateApiToken": "APIトークンを生成"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +187,14 @@
|
||||
"Disconnected": "Desconectado",
|
||||
"Available": "Disponível",
|
||||
"NotConnectedIntegration": "A conta {account} não está integrada com o espaço de trabalho",
|
||||
"IntegrationIsUnstable": "O serviço de integração está enfrentando problemas. Algumas funcionalidades podem não funcionar corretamente."
|
||||
"IntegrationIsUnstable": "O serviço de integração está enfrentando problemas. Algumas funcionalidades podem não funcionar corretamente.",
|
||||
"MinValue": "Valor mínimo",
|
||||
"MaxValue": "Valor máximo",
|
||||
"IntegerOnly": "Apenas números inteiros",
|
||||
"AccessControl": "Controle de acesso",
|
||||
"DangerZone": "Zona de perigo",
|
||||
"ApiAccess": "Acesso à API",
|
||||
"ApiToken": "Token de API",
|
||||
"GenerateApiToken": "Gerar token de API"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"Disconnected": "Отключено",
|
||||
"Available": "Доступно",
|
||||
"NotConnectedIntegration": "Учетная запись {account} не интегрирована с рабочим пространством",
|
||||
"IntegrationIsUnstable": "Сервис интеграции испытывает проблемы. Некоторые функции могут работать некорректно."
|
||||
"IntegrationIsUnstable": "Сервис интеграции испытывает проблемы. Некоторые функции могут работать некорректно.",
|
||||
"AccessControl": "Контроль доступа",
|
||||
"DangerZone": "Опасная зона",
|
||||
"ApiAccess": "Доступ к API",
|
||||
"ApiToken": "API токен",
|
||||
"GenerateApiToken": "Создать API токен"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"IntegrationIsUnstable": "Entegrasyon servisi sorunlar yaşıyor. Bazı özellikler düzgün çalışmayabilir.",
|
||||
"MinValue": "Minimum değer",
|
||||
"MaxValue": "Maksimum değer",
|
||||
"IntegerOnly": "Sadece tam sayılar"
|
||||
"IntegerOnly": "Sadece tam sayılar",
|
||||
"AccessControl": "Erişim kontrolü",
|
||||
"DangerZone": "Tehlike bölgesi",
|
||||
"ApiAccess": "API erişimi",
|
||||
"ApiToken": "API token",
|
||||
"GenerateApiToken": "API token oluştur"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
"IntegrationIsUnstable": "集成服务出现问题。某些功能可能无法正常工作。",
|
||||
"MinValue": "最小值",
|
||||
"MaxValue": "最大值",
|
||||
"IntegerOnly": "仅整数"
|
||||
"IntegerOnly": "仅整数",
|
||||
"AccessControl": "访问控制",
|
||||
"DangerZone": "危险区域",
|
||||
"ApiAccess": "API访问",
|
||||
"ApiToken": "API令牌",
|
||||
"GenerateApiToken": "生成API令牌"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<!--
|
||||
// Copyright © 2025 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 { Timestamp } from '@hcengineering/core'
|
||||
import presentation, { copyTextToClipboard } from '@hcengineering/presentation'
|
||||
import view from '@hcengineering/view'
|
||||
import { Button, Label, ticker } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import settings from '../plugin'
|
||||
|
||||
export let token: string
|
||||
|
||||
const isSecureContext = window.isSecureContext
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let copiedTime: Timestamp | undefined
|
||||
let copied = false
|
||||
|
||||
$: if (copiedTime !== undefined && copied && $ticker - copiedTime > 1000) {
|
||||
copied = false
|
||||
}
|
||||
|
||||
async function copy (): Promise<void> {
|
||||
if (!isSecureContext) return
|
||||
if (token === undefined) return
|
||||
|
||||
await copyTextToClipboard(token)
|
||||
copied = true
|
||||
copiedTime = Date.now()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiPopup popup" class:secure={isSecureContext}>
|
||||
<div class="overflow-label fs-title mb-4">
|
||||
<Label label={settings.string.ApiToken} />
|
||||
</div>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div class="token" class:notSecure={!isSecureContext} class:over-underline={isSecureContext} on:click={copy}>
|
||||
{token}
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<Button
|
||||
label={presentation.string.Close}
|
||||
size={'medium'}
|
||||
kind={'primary'}
|
||||
on:click={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
/>
|
||||
{#if isSecureContext}
|
||||
<Button label={copied ? view.string.Copied : view.string.CopyToClipboard} size={'medium'} on:click={copy} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.popup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.75rem;
|
||||
width: 30rem;
|
||||
max-width: 40rem;
|
||||
background: var(--popup-bg-color);
|
||||
border-radius: 1.25rem;
|
||||
user-select: none;
|
||||
box-shadow: var(--popup-shadow);
|
||||
|
||||
.token {
|
||||
margin: 1.75rem 0 0;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
&.notSecure {
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin-top: 1.75rem;
|
||||
flex-shrink: 0;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
direction: rtl;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
column-gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
<Scroller padding={'1.5rem'} noStretch>
|
||||
{#if loading}
|
||||
<Loading size={'small'} />
|
||||
<Loading />
|
||||
{:else if backupInfo == null}
|
||||
<div class="no-backups">
|
||||
<Label label={setting.string.BackupNoBackup} />
|
||||
|
||||
@@ -37,13 +37,12 @@
|
||||
Header,
|
||||
IconCheckmark,
|
||||
IconClose,
|
||||
IconDelete,
|
||||
IconEdit,
|
||||
Label,
|
||||
Loading,
|
||||
navigate,
|
||||
Scroller,
|
||||
showPopup,
|
||||
Spinner,
|
||||
themeStore,
|
||||
Toggle
|
||||
} from '@hcengineering/ui'
|
||||
@@ -57,11 +56,13 @@
|
||||
import communication, { GuestCommunicationSettings } from '@hcengineering/communication'
|
||||
import card, { Card } from '@hcengineering/card'
|
||||
import chat from '@hcengineering/chat'
|
||||
import ApiTokenPopup from './ApiTokenPopup.svelte'
|
||||
|
||||
let loading = true
|
||||
let isEditingName = false
|
||||
let oldName: string
|
||||
let name: string = ''
|
||||
let workspaceUrl = ''
|
||||
let allowReadOnlyGuests: boolean
|
||||
let allowGuestSignUp: boolean
|
||||
|
||||
@@ -80,6 +81,7 @@
|
||||
async function loadWorkspaceName (): Promise<void> {
|
||||
const res = await accountClient.getWorkspaceInfo()
|
||||
|
||||
workspaceUrl = res.url
|
||||
oldName = res.name
|
||||
name = oldName
|
||||
allowReadOnlyGuests = res.allowReadOnlyGuest ?? false
|
||||
@@ -126,25 +128,26 @@
|
||||
})
|
||||
|
||||
async function handleAvatarDone (): Promise<void> {
|
||||
if (workspaceSettings === undefined) {
|
||||
const existing = await client.findOne(settingsRes.class.WorkspaceSetting, { _id: settingsRes.ids.WorkspaceSetting })
|
||||
if (existing !== undefined) {
|
||||
const avatar = await avatarEditor.createAvatar()
|
||||
// Remove old avatar if changed
|
||||
if (existing.icon != null && existing.icon !== avatar.avatar) {
|
||||
await avatarEditor.removeAvatar(existing.icon)
|
||||
}
|
||||
|
||||
const icon = avatar.avatarType === AvatarType.IMAGE ? avatar.avatar : null
|
||||
await client.diffUpdate(existing, { icon })
|
||||
} else {
|
||||
const avatar = await avatarEditor.createAvatar()
|
||||
|
||||
await client.createDoc(
|
||||
settingsRes.class.WorkspaceSetting,
|
||||
core.space.Workspace,
|
||||
{ icon: avatar.avatar },
|
||||
settingsRes.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 permissionConfigurationQuery = createQuery()
|
||||
@@ -193,6 +196,11 @@
|
||||
await accountClient.updateAllowGuestSignUp(e.detail)
|
||||
}
|
||||
|
||||
async function handleGenerateApiToken (): Promise<void> {
|
||||
const { token } = await accountClient.selectWorkspace(workspaceUrl)
|
||||
showPopup(ApiTokenPopup, { token })
|
||||
}
|
||||
|
||||
function handleTogglePermissions (): void {
|
||||
const newState = !arePermissionsDisabled
|
||||
showPopup(MessageBox, {
|
||||
@@ -268,11 +276,13 @@
|
||||
|
||||
<div class="hulyComponent">
|
||||
<Header adaptive={'disabled'}>
|
||||
<Breadcrumb icon={settingsRes.icon.Setting} label={settingsRes.string.General} size={'large'} isCurrent />
|
||||
<Breadcrumb icon={settingsRes.icon.Setting} label={settingsRes.string.WorkspaceSettings} size={'large'} isCurrent />
|
||||
</Header>
|
||||
<div class="hulyComponent-content__column content">
|
||||
{#if loading}
|
||||
<Spinner size={'small'} />
|
||||
<div class="w-full h-full flex-col-center justify-center">
|
||||
<Loading />
|
||||
</div>
|
||||
{:else}
|
||||
<Scroller align={'center'} padding={'var(--spacing-3)'} bottomPadding={'var(--spacing-3)'}>
|
||||
<div class="hulyComponent-content flex-col flex-gap-4">
|
||||
@@ -280,10 +290,11 @@
|
||||
<div class="ws">
|
||||
<EditableAvatar
|
||||
person={{
|
||||
avatarType: AvatarType.IMAGE,
|
||||
avatarType: workspaceSettings?.icon !== undefined ? AvatarType.IMAGE : AvatarType.COLOR,
|
||||
avatar: workspaceSettings?.icon
|
||||
}}
|
||||
size="medium"
|
||||
{name}
|
||||
bind:this={avatarEditor}
|
||||
on:done={handleAvatarDone}
|
||||
imageOnly
|
||||
@@ -307,13 +318,8 @@
|
||||
{#if isEditingName}
|
||||
<Button icon={IconClose} kind="ghost" size="small" on:click={handleCancelEditName} />
|
||||
{/if}
|
||||
<Button
|
||||
icon={IconDelete}
|
||||
kind="dangerous"
|
||||
on:click={handleDelete}
|
||||
showTooltip={{ label: settingsRes.string.DeleteWorkspace }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-col flex-gap-4 mt-6">
|
||||
<div class="title"><Label label={settingsRes.string.Calendar} /></div>
|
||||
<div class="flex-row-center flex-gap-4">
|
||||
@@ -328,46 +334,80 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title mt-6"><Label label={settingsRes.string.GuestAccess} /></div>
|
||||
<div class="flex-row-center flex-gap-4">
|
||||
<Label label={settingsRes.string.GuestAccessDescription} />
|
||||
<Toggle
|
||||
on={allowReadOnlyGuests}
|
||||
on:change={(e) => {
|
||||
void handleToggleReadonlyAccess(e)
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="flex-col flex-gap-4 mt-6">
|
||||
<div class="title"><Label label={settingsRes.string.GuestAccess} /></div>
|
||||
<div class="flex-row-center flex-gap-4">
|
||||
<Label label={settingsRes.string.GuestAccessDescription} />
|
||||
<Toggle
|
||||
on={allowReadOnlyGuests}
|
||||
on:change={(e) => {
|
||||
void handleToggleReadonlyAccess(e)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-row-center flex-gap-4">
|
||||
<Label label={settingsRes.string.GuestSignUpDescription} />
|
||||
<Toggle
|
||||
disabled={!allowReadOnlyGuests}
|
||||
on={allowGuestSignUp}
|
||||
on:change={(e) => {
|
||||
void handleToggleGuestSignUp(e)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-row-center flex-gap-4">
|
||||
<Label label={settingsRes.string.GuestChannelsDescription} />
|
||||
<Component
|
||||
is={card.component.CardArrayEditor}
|
||||
props={{
|
||||
_class: chat.masterTag.Thread,
|
||||
value: existingGuestChatSettings !== undefined ? existingGuestChatSettings.allowedCards : [],
|
||||
label: settingsRes.string.GuestChannelsArrayLabel,
|
||||
onChange: onAllowedCardsChange
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-row-center flex-gap-4">
|
||||
<Label label={settingsRes.string.GuestSignUpDescription} />
|
||||
<Toggle
|
||||
disabled={!allowReadOnlyGuests}
|
||||
on={allowGuestSignUp}
|
||||
on:change={(e) => {
|
||||
void handleToggleGuestSignUp(e)
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="flex-col flex-gap-4 mt-6">
|
||||
<div class="title"><Label label={settingsRes.string.AccessControl} /></div>
|
||||
<div class="w-32">
|
||||
<Button
|
||||
kind="regular"
|
||||
label={arePermissionsDisabled
|
||||
? settingsRes.string.EnablePermissions
|
||||
: settingsRes.string.DisablePermissions}
|
||||
on:click={handleTogglePermissions}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-row-center flex-gap-4">
|
||||
<Label label={settingsRes.string.GuestChannelsDescription} />
|
||||
<Component
|
||||
is={card.component.CardArrayEditor}
|
||||
props={{
|
||||
_class: chat.masterTag.Thread,
|
||||
value: existingGuestChatSettings !== undefined ? existingGuestChatSettings.allowedCards : [],
|
||||
label: settingsRes.string.GuestChannelsArrayLabel,
|
||||
onChange: onAllowedCardsChange
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="flex-col flex-gap-4 mt-6">
|
||||
<div class="title"><Label label={settingsRes.string.ApiAccess} /></div>
|
||||
<div class="w-32">
|
||||
<Button
|
||||
label={settingsRes.string.GenerateApiToken}
|
||||
kind="regular"
|
||||
disabled={workspaceUrl === ''}
|
||||
showTooltip={{ label: settingsRes.string.GenerateApiToken }}
|
||||
on:click={handleGenerateApiToken}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="delete">
|
||||
<Button
|
||||
kind="regular"
|
||||
label={arePermissionsDisabled
|
||||
? settingsRes.string.EnablePermissions
|
||||
: settingsRes.string.DisablePermissions}
|
||||
on:click={handleTogglePermissions}
|
||||
/>
|
||||
|
||||
<div class="flex-col flex-gap-4 mt-6">
|
||||
<div class="title"><Label label={settingsRes.string.DangerZone} /></div>
|
||||
<div class="w-32">
|
||||
<Button
|
||||
label={settingsRes.string.DeleteWorkspace}
|
||||
kind="dangerous"
|
||||
on:click={handleDelete}
|
||||
showTooltip={{ label: settingsRes.string.DeleteWorkspace }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Scroller>
|
||||
@@ -389,8 +429,4 @@
|
||||
.editBox {
|
||||
width: 16rem;
|
||||
}
|
||||
|
||||
.delete {
|
||||
width: 6rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -131,12 +131,6 @@
|
||||
<Label label={setting.string.Primary} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if canRelease}
|
||||
<div class="on-hover">
|
||||
<Button label={setting.string.Release} kind="ghost" on:click={handleRelease} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -129,11 +129,16 @@ export default mergeIds(settingId, setting, {
|
||||
DisablePermissionsConfirmation: '' as IntlString,
|
||||
EnablePermissionsConfirmation: '' as IntlString,
|
||||
BetaWarning: '' as IntlString,
|
||||
DangerZone: '' as IntlString,
|
||||
AccessControl: '' as IntlString,
|
||||
GuestAccess: '' as IntlString,
|
||||
GuestAccessDescription: '' as IntlString,
|
||||
GuestSignUpDescription: '' as IntlString,
|
||||
GuestChannelsDescription: '' as IntlString,
|
||||
GuestChannelsArrayLabel: '' as IntlString,
|
||||
ApiAccess: '' as IntlString,
|
||||
ApiToken: '' as IntlString,
|
||||
GenerateApiToken: '' as IntlString,
|
||||
ManageIdentities: '' as IntlString,
|
||||
AddNew: '' as IntlString,
|
||||
Release: '' as IntlString,
|
||||
|
||||
Reference in New Issue
Block a user