mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-22 08:26:16 -04:00
Begin redesigning admin panel. (#6219)
* Begin redesigning admin panel. * Added monaco editor. * Fixed tests
This commit is contained in:
parent
4add6eb313
commit
73dff0bfe7
26 changed files with 252 additions and 56 deletions
|
@ -3,6 +3,9 @@ import {useEffect, useMemo, useState} from "react";
|
|||
import {InstalledPlugin, PluginDef, SearchParams} from "./Plugin.ts";
|
||||
import {useDebounce} from "../utils/useDebounce.ts";
|
||||
import {Trans, useTranslation} from "react-i18next";
|
||||
import {SearchField} from "../components/SearchField.tsx";
|
||||
import {Download, Trash} from "lucide-react";
|
||||
import {IconButton} from "../components/IconButton.tsx";
|
||||
|
||||
|
||||
export const HomePage = () => {
|
||||
|
@ -128,12 +131,12 @@ export const HomePage = () => {
|
|||
|
||||
<h2><Trans i18nKey="admin_plugins.installed"/></h2>
|
||||
|
||||
<table>
|
||||
<table id="installed-plugins">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><Trans i18nKey="admin_plugins.name"/></th>
|
||||
<th><Trans i18nKey="admin_plugins.version"/></th>
|
||||
<th></th>
|
||||
<th><Trans i18nKey="ep_admin_pads:ep_adminpads2_action"/></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style={{overflow: 'auto'}}>
|
||||
|
@ -145,10 +148,7 @@ export const HomePage = () => {
|
|||
{
|
||||
plugin.updatable ?
|
||||
<button onClick={() => installPlugin(plugin.name)}>Update</button>
|
||||
: <button disabled={plugin.name == "ep_etherpad-lite"}
|
||||
onClick={() => uninstallPlugin(plugin.name)}><Trans
|
||||
i18nKey="admin_plugins.installed_uninstall.value"/></button>
|
||||
|
||||
: <IconButton disabled={plugin.name == "ep_etherpad-lite"} icon={<Trash/>} title={<Trans i18nKey="admin_plugins.installed_uninstall.value"/>} onClick={() => uninstallPlugin(plugin.name)}/>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -158,19 +158,16 @@ export const HomePage = () => {
|
|||
|
||||
|
||||
<h2><Trans i18nKey="admin_plugins.available"/></h2>
|
||||
<SearchField onChange={v=>{setSearchTerm(v.target.value)}} placeholder={t('admin_plugins.available_search.placeholder')} value={searchTerm}/>
|
||||
|
||||
<input className="search-field" placeholder={t('admin_plugins.available_search.placeholder')} type="text" value={searchTerm} onChange={v=>{
|
||||
setSearchTerm(v.target.value)
|
||||
}}/>
|
||||
|
||||
<table>
|
||||
<table id="available-plugins">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><Trans i18nKey="admin_plugins.name"/></th>
|
||||
<th style={{width: '30%'}}><Trans i18nKey="admin_plugins.description"/></th>
|
||||
<th><Trans i18nKey="admin_plugins.version"/></th>
|
||||
<th><Trans i18nKey="admin_plugins.last-update"/></th>
|
||||
<th></th>
|
||||
<th><Trans i18nKey="ep_admin_pads:ep_adminpads2_action"/></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style={{overflow: 'auto'}}>
|
||||
|
@ -181,7 +178,7 @@ export const HomePage = () => {
|
|||
<td>{plugin.version}</td>
|
||||
<td>{plugin.time}</td>
|
||||
<td>
|
||||
<button onClick={() => installPlugin(plugin.name)}><Trans i18nKey="admin_plugins.available_install.value"/></button>
|
||||
<IconButton icon={<Download/>} onClick={() => installPlugin(plugin.name)} title={<Trans i18nKey="admin_plugins.available_install.value"/>}/>
|
||||
</td>
|
||||
</tr>
|
||||
})}
|
||||
|
|
|
@ -5,6 +5,9 @@ import {PadSearchQuery, PadSearchResult} from "../utils/PadSearch.ts";
|
|||
import {useDebounce} from "../utils/useDebounce.ts";
|
||||
import {determineSorting} from "../utils/sorting.ts";
|
||||
import * as Dialog from "@radix-ui/react-dialog";
|
||||
import {IconButton} from "../components/IconButton.tsx";
|
||||
import {Trash2} from "lucide-react";
|
||||
import {SearchField} from "../components/SearchField.tsx";
|
||||
|
||||
export const PadPage = ()=>{
|
||||
const settingsSocket = useStore(state=>state.settingsSocket)
|
||||
|
@ -98,8 +101,7 @@ export const PadPage = ()=>{
|
|||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
<h1><Trans i18nKey="ep_admin_pads:ep_adminpads2_manage-pads"/></h1>
|
||||
<input type="text" value={searchTerm} onChange={v=>setSearchTerm(v.target.value)}
|
||||
placeholder={t('ep_admin_pads:ep_adminpads2_search-heading')}/>
|
||||
<SearchField value={searchTerm} onChange={v=>setSearchTerm(v.target.value)} placeholder={t('ep_admin_pads:ep_adminpads2_search-heading')}/>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -144,13 +146,11 @@ export const PadPage = ()=>{
|
|||
<td style={{textAlign: 'center'}}>{pad.revisionNumber}</td>
|
||||
<td>
|
||||
<div className="settings-button-bar">
|
||||
<button onClick={()=>{
|
||||
<IconButton icon={<Trash2/>} title={<Trans i18nKey="ep_admin_pads:ep_adminpads2_delete.value"/>} onClick={()=>{
|
||||
setPadToDelete(pad.padName)
|
||||
setDeleteDialog(true)
|
||||
}}><Trans i18nKey="ep_admin_pads:ep_adminpads2_delete.value"/></button>
|
||||
<button onClick={()=>{
|
||||
window.open(`/p/${pad.padName}`, '_blank')
|
||||
}}>view</button>
|
||||
}}/>
|
||||
<IconButton icon={<Trash2/>} title="view" onClick={()=>window.open(`/p/${pad.padName}`, '_blank')}/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import {useStore} from "../store/store.ts";
|
||||
import {isJSONClean} from "../utils/utils.ts";
|
||||
import {Trans} from "react-i18next";
|
||||
import {IconButton} from "../components/IconButton.tsx";
|
||||
import {RotateCw, Save} from "lucide-react";
|
||||
|
||||
export const SettingsPage = ()=>{
|
||||
const settingsSocket = useStore(state=>state.settingsSocket)
|
||||
|
||||
const settings = useStore(state=>state.settings)
|
||||
|
||||
return <div>
|
||||
|
@ -13,7 +14,8 @@ export const SettingsPage = ()=>{
|
|||
useStore.getState().setSettings(v.target.value)
|
||||
}}/>
|
||||
<div className="settings-button-bar">
|
||||
<button className="settingsButton" onClick={() => {
|
||||
<IconButton className="settingsButton" icon={<Save/>}
|
||||
title={<Trans i18nKey="admin_settings.current_save.value"/>} onClick={() => {
|
||||
if (isJSONClean(settings!)) {
|
||||
// JSON is clean so emit it to the server
|
||||
settingsSocket!.emit('saveSettings', settings!);
|
||||
|
@ -29,16 +31,19 @@ export const SettingsPage = ()=>{
|
|||
success: false
|
||||
})
|
||||
}
|
||||
}}><Trans i18nKey="admin_settings.current_save.value"/></button>
|
||||
<button className="settingsButton" onClick={() => {
|
||||
}}/>
|
||||
<IconButton className="settingsButton" icon={<RotateCw/>}
|
||||
title={<Trans i18nKey="admin_settings.current_restart.value"/>} onClick={() => {
|
||||
settingsSocket!.emit('restartServer');
|
||||
}}><Trans i18nKey="admin_settings.current_restart.value"/></button>
|
||||
}}/>
|
||||
</div>
|
||||
<div className="separator"/>
|
||||
<div className="settings-button-bar">
|
||||
<a rel="noopener noreferrer" target="_blank" href="https://github.com/ether/etherpad-lite/wiki/Example-Production-Settings.JSON"><Trans
|
||||
<a rel="noopener noreferrer" target="_blank"
|
||||
href="https://github.com/ether/etherpad-lite/wiki/Example-Production-Settings.JSON"><Trans
|
||||
i18nKey="admin_settings.current_example-prod"/></a>
|
||||
<a rel="noopener noreferrer" target="_blank" href="https://github.com/ether/etherpad-lite/wiki/Example-Development-Settings.JSON"><Trans
|
||||
<a rel="noopener noreferrer" target="_blank"
|
||||
href="https://github.com/ether/etherpad-lite/wiki/Example-Development-Settings.JSON"><Trans
|
||||
i18nKey="admin_settings.current_example-devel"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue