Unverified Commit 7f4417ee authored by NGPixel's avatar NGPixel

fix: various fixes + improvements

parent e492371c
......@@ -8,7 +8,8 @@
"workspaceFolder": "/workspace",
"shutdownAction": "stopCompose",
// Set *default* container specific settings.json values on container create.
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh",
"sqltools.connections": [
......@@ -26,8 +27,6 @@
}
]
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"arcanis.vscode-zipfs",
"dbaeumer.vscode-eslint",
......@@ -43,7 +42,9 @@
"mutantdino.resourcemonitor",
"wayou.vscode-todo-highlight",
"GraphQL.vscode-graphql"
],
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// This can be used to network with other containers or with the host.
......
......@@ -45,6 +45,7 @@ services:
- PGADMIN_DISABLE_POSTFIX=True
- PGADMIN_LISTEN_PORT=8000
- PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=False
- PGADMIN_CONFIG_LOGIN_BANNER="Login with dev@js.wiki / 123123"
network_mode: service:db
# volumes:
# - ./pgadmin-servers.json:/pgadmin4/servers.json
......
<div align="center">
<img src="https://static.requarks.io/logo/wikijs-full.svg" alt="Wiki.js" width="600" />
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://static.requarks.io/logo/wikijs-full-darktheme.svg">
<img alt="Wiki.js" src="https://static.requarks.io/logo/wikijs-full.svg" width="600">
</picture>
[![License](https://img.shields.io/badge/license-AGPLv3-blue.svg?style=flat)](https://github.com/requarks/wiki/blob/master/LICENSE)
[![Standard - JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-green.svg?style=flat&logo=javascript&logoColor=white)](http://standardjs.com/)
......@@ -27,66 +30,34 @@ The current stable release (2.x) is available at https://js.wiki
---
- [Generic Setup](#generic-setup)
- [Requirements](#requirements)
- [Usage](#usage)
- [Using VS Code Dev Environment](#using-vs-code-dev-environment) *(recommended)*
- [Requirements](#requirements-1)
- [Usage](#usage-1)
- [Usage](#usage)
- [Server Development](#server-development)
- [Frontend Development (Quasar/Vue 3)](#frontend-development-quasarvue-3)
- [pgAdmin](#pgadmin)
## Generic Setup
### Requirements
- Node.js **18.x** or later
- PostgreSQL **11** or later
### Usage
1. Clone the project
1. Make a copy of `config.sample.yml` and rename it to `config.yml`
1. Edit `config.yml` and fill in the database details. **You need an empty PostgreSQL database.**
1. Run the following commands to install dependencies and generate the client assets:
```sh
cd server
npm install
cd ../ux
npm install
npm run build
cd ..
```
1. Run this command to start the server:
```sh
node server
```
1. In your browser, navigate to `http://localhost:3000` *(or the IP/hostname of the server and the PORT you defined earlier.)*
1. Login using the default administrator user:
- Email: `admin@example.com`
- Password: `12345678`
> **DO NOT** report bugs. This build is **VERY** buggy and **VERY** incomplete. Absolutely **NO** support is provided either.
- [Generic Setup](#generic-setup)
- [Requirements](#requirements)
- [Usage](#usage-1)
## Using VS Code Dev Environment
### Requirements
- VS Code
- Docker Desktop
- **Windows-only:** WSL 2 + WSL Integration enabled in Docker Desktop
- [VS Code](https://code.visualstudio.com/)
- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
- **Windows-only:** [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install) + [WSL Integration](https://docs.docker.com/desktop/wsl/) enabled in Docker Desktop
### Usage
1. Clone the project.
1. Open the project in VS Code.
1. Make sure you have **Dev Containers** extension installed. (On Windows, you need the **WSL** VS Code extension as well.)
1. Reopen the project in container (from the popup in the lower-right corner of the screen when opening the project, or via the Command Palette (Ctrl+Shift+P) afterwards).
1. Reopen the project in container (from the popup in the lower-right corner of the screen when opening the project, or via the Command Palette (Ctrl+Shift+P *or* F1) afterwards).
1. Once in container mode, make a copy of `config.sample.yml` and rename it to `config.yml`. There's no need to edit the file, the default values are ok.
1. From the Command Palette, run the task "Create terminals":
- Launch the Command Palette (Ctrl+Shift+P)
- Type "Run Task" and press Enter
- Launch the Command Palette (Ctrl+Shift+P *or* F1)
- Type `Run Task` and press <kbd>Enter</kbd>
- Select the task "Create terminals" and press Enter
1. Two terminals will launch in split-screen mode at the bottom of the screen. **Server** on the left and **UX** on the right.
1. In the right-side terminal (UX), run the command:
......@@ -116,7 +87,7 @@ This will launch the server and automatically restart upon modification of any s
Only precompiled client assets are served in this mode. See the sections below on how to modify the frontend and run in SPA (Single Page Application) mode.
### Frontend Development (Quasar/Vue 3)
### Frontend Development
> Make sure you are running `npm run dev` in the left-side terminal (Server) first! Requests still need to be forwarded to the server, even in SPA mode!
......@@ -141,3 +112,35 @@ The server **dev** should already be available under **Servers**. If that's not
- Username: `postgres`
- Password: `postgres`
- Database: `postgres`
## Generic Setup
### Requirements
- Node.js **18.x** or later
- PostgreSQL **11** or later
### Usage
1. Clone the project
1. Make a copy of `config.sample.yml` and rename it to `config.yml`
1. Edit `config.yml` and fill in the database details. **You need an empty PostgreSQL database.**
1. Run the following commands to install dependencies and generate the client assets:
```sh
cd server
npm install
cd ../ux
npm install
npm run build
cd ..
```
1. Run this command to start the server:
```sh
node server
```
1. In your browser, navigate to `http://localhost:3000` *(or the IP/hostname of the server and the PORT you defined earlier.)*
1. Login using the default administrator user:
- Email: `admin@example.com`
- Password: `12345678`
> **DO NOT** report bugs. This build is **VERY** buggy and **VERY** incomplete. Absolutely **NO** support is provided either.
version: '3.8'
services:
db:
image: postgres:latest
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: postgres
ports:
- "5432:5432"
pgadmin:
image: dpage/pgadmin4:latest
environment:
- PGADMIN_DEFAULT_EMAIL=dev@js.wiki
- PGADMIN_DEFAULT_PASSWORD=123123
- PGADMIN_DISABLE_POSTFIX=True
- PGADMIN_LISTEN_PORT=8000
- PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=False
ports:
- "8000:8000"
volumes:
postgres-data:
......@@ -336,7 +336,7 @@
"admin.groups.ruleUntitled": "Untitled Rule",
"admin.groups.rules": "Rules",
"admin.groups.rulesNone": "This group doesn't have any rules yet.",
"admin.groups.selectedLocales": "Any Locale | {locale} locale only | {count} locales selected",
"admin.groups.selectedLocales": "Any Locale | {n} locale only | {count} locales selected",
"admin.groups.selectedSites": "Any Site | 1 site selected | {count} sites selected",
"admin.groups.subtitle": "Manage user groups and permissions",
"admin.groups.title": "Groups",
......@@ -1216,6 +1216,7 @@
"common.actions.rename": "Rename",
"common.actions.returnToTop": "Return to top",
"common.actions.save": "Save",
"common.actions.saveAndClose": "Save and Close",
"common.actions.saveChanges": "Save Changes",
"common.actions.select": "Select",
"common.actions.update": "Update",
......
......@@ -575,7 +575,6 @@ export class User extends Model {
tfaSecret: ''
}
},
localeCode: 'en',
hasAvatar: false,
isSystem: false,
isActive: true,
......
......@@ -34,21 +34,21 @@
"node": ">=18.0"
},
"dependencies": {
"@apollo/server": "4.7.3",
"@apollo/server": "4.7.5",
"@azure/storage-blob": "12.14.0",
"@exlinc/keycloak-passport": "1.0.2",
"@graphql-tools/schema": "10.0.0",
"@graphql-tools/utils": "10.0.1",
"@joplin/turndown-plugin-gfm": "1.0.47",
"@joplin/turndown-plugin-gfm": "1.0.49",
"@root/csr": "0.8.1",
"@root/keypairs": "0.10.3",
"@root/pem": "1.0.4",
"acme": "3.0.3",
"akismet-api": "6.0.0",
"aws-sdk": "2.1395.0",
"aws-sdk": "2.1409.0",
"bcryptjs": "2.4.3",
"body-parser": "1.20.2",
"chalk": "5.2.0",
"chalk": "5.3.0",
"cheerio": "1.0.0-rc.12",
"chokidar": "3.5.3",
"chromium-pickle-js": "0.2.0",
......@@ -64,7 +64,7 @@
"dependency-graph": "0.11.0",
"diff": "5.1.0",
"diff2html": "3.4.35",
"dompurify": "3.0.3",
"dompurify": "3.0.4",
"dotize": "0.3.0",
"emoji-regex": "10.2.1",
"eventemitter2": "6.4.9",
......@@ -75,14 +75,14 @@
"filesize": "10.0.7",
"fs-extra": "11.1.1",
"getos": "3.2.1",
"graphql": "16.6.0",
"graphql": "16.7.1",
"graphql-list-fields": "2.0.2",
"graphql-rate-limit-directive": "2.0.3",
"graphql-tools": "9.0.0",
"graphql-upload": "16.0.2",
"he": "1.2.0",
"highlight.js": "11.8.0",
"i18next": "22.5.1",
"i18next": "23.2.6",
"i18next-node-fs-backend": "2.1.3",
"image-size": "1.0.2",
"js-base64": "3.7.5",
......@@ -90,7 +90,7 @@
"js-yaml": "4.1.0",
"jsdom": "22.1.0",
"jsonwebtoken": "9.0.0",
"katex": "0.16.7",
"katex": "0.16.8",
"klaw": "4.1.0",
"knex": "2.4.2",
"lodash": "4.17.21",
......@@ -117,7 +117,7 @@
"node-2fa": "2.0.3",
"node-cache": "5.1.2",
"nodemailer": "6.9.3",
"objection": "3.0.1",
"objection": "3.0.4",
"passport": "0.6.0",
"passport-auth0": "1.4.3",
"passport-azure-ad": "4.3.5",
......@@ -139,14 +139,14 @@
"passport-slack-oauth2": "1.2.0",
"passport-twitch-strategy": "2.2.0",
"pem-jwk": "2.0.0",
"pg": "8.11.0",
"pg": "8.11.1",
"pg-hstore": "2.3.4",
"pg-pubsub": "0.8.1",
"pg-query-stream": "4.5.0",
"pg-query-stream": "4.5.1",
"pg-tsquery": "8.4.1",
"poolifier": "2.6.2",
"poolifier": "2.6.5",
"punycode": "2.3.0",
"puppeteer-core": "20.5.0",
"puppeteer-core": "20.7.4",
"qr-image": "3.2.0",
"rate-limiter-flexible": "2.4.1",
"remove-markdown": "0.5.0",
......@@ -155,13 +155,13 @@
"safe-regex": "2.1.1",
"sanitize-filename": "1.6.3",
"scim-query-filter-parser": "2.0.4",
"semver": "7.5.1",
"semver": "7.5.3",
"serve-favicon": "2.5.0",
"sharp": "0.32.1",
"simple-git": "3.19.0",
"socket.io": "4.6.2",
"simple-git": "3.19.1",
"socket.io": "4.7.1",
"striptags": "3.2.0",
"tar-fs": "2.1.1",
"tar-fs": "3.0.3",
"turndown": "7.1.2",
"twemoji": "14.0.2",
"uslug": "1.0.4",
......@@ -171,7 +171,7 @@
"yargs": "17.7.2"
},
"devDependencies": {
"eslint": "8.42.0",
"eslint": "8.44.0",
"eslint-config-requarks": "1.0.7",
"eslint-config-standard": "17.1.0",
"eslint-plugin-import": "2.27.5",
......
# Wiki.js (ux)
The most powerful and extensible open source Wiki software
## Install the dependencies
```bash
yarn
# or
npm install
```
### Start the app in development mode (hot-code reloading, error reporting, etc.)
```bash
quasar dev
```
### Lint the files
```bash
yarn lint
# or
npm run lint
```
### Build the app for production
```bash
quasar build
```
### Customize the configuration
See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js).
......@@ -13,7 +13,7 @@
"ncu-u": "ncu -u -x codemirror,codemirror-asciidoc"
},
"dependencies": {
"@apollo/client": "3.7.15",
"@apollo/client": "3.7.16",
"@lezer/common": "1.0.3",
"@mdi/font": "7.2.96",
"@quasar/extras": "1.16.4",
......@@ -56,7 +56,7 @@
"highlight.js": "11.8.0",
"js-cookie": "3.0.5",
"jwt-decode": "3.1.2",
"katex": "0.16.7",
"katex": "0.16.8",
"lodash-es": "4.17.21",
"lowlight": "2.9.0",
"luxon": "3.3.0",
......@@ -76,7 +76,7 @@
"mitt": "3.0.0",
"monaco-editor": "0.39.0",
"pako": "2.1.0",
"pinia": "2.1.3",
"pinia": "2.1.4",
"prosemirror-commands": "1.5.2",
"prosemirror-history": "1.3.2",
"prosemirror-keymap": "1.2.2",
......@@ -84,16 +84,16 @@
"prosemirror-schema-list": "1.3.0",
"prosemirror-state": "1.4.3",
"prosemirror-transform": "1.7.3",
"prosemirror-view": "1.31.4",
"prosemirror-view": "1.31.5",
"pug": "3.0.2",
"quasar": "2.12.0",
"quasar": "2.12.1",
"slugify": "1.6.6",
"socket.io-client": "4.6.2",
"socket.io-client": "4.7.1",
"tabulator-tables": "5.5.0",
"tippy.js": "6.3.7",
"twemoji": "14.0.2",
"uuid": "9.0.0",
"v-network-graph": "0.9.3",
"v-network-graph": "0.9.4",
"vue": "3.3.4",
"vue-i18n": "9.2.2",
"vue-router": "4.2.2",
......@@ -109,12 +109,12 @@
"@volar/vue-language-plugin-pug": "1.6.5",
"autoprefixer": "10.4.14",
"browserlist": "latest",
"eslint": "8.42.0",
"eslint": "8.44.0",
"eslint-config-standard": "17.1.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-n": "16.0.0",
"eslint-plugin-n": "16.0.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-vue": "9.14.1"
"eslint-plugin-vue": "9.15.1"
},
"engines": {
"node": ">= 18.0",
......
......@@ -825,6 +825,9 @@ async function uploadNewFiles () {
idx++
state.uploadPercentage = totalFiles > 1 ? Math.round(idx / totalFiles * 100) : 90
const resp = await APOLLO_CLIENT.mutate({
context: {
uploadMode: true
},
mutation: gql`
mutation uploadAssets (
$folderId: UUID
......
......@@ -152,7 +152,7 @@ q-layout(view='hHh lpR fFf', container)
flat
color='grey'
type='a'
href='https://docs.js.wiki/admin/groups#rules'
:href='siteStore.docsBase + `/admin/groups#rules`'
target='_blank'
)
q-btn.acrylic-btn.q-mr-sm(
......@@ -221,12 +221,21 @@ q-layout(view='hHh lpR fFf', container)
use-chips
stack-label
)
template(v-slot:selected-item='scope')
q-chip(
square
dense
:tabindex='scope.tabindex'
:color='getRuleModeBgColor(rule.mode)'
text-color='white'
)
span.text-caption {{ scope.opt.title }}
template(v-slot:option='{ itemProps, itemEvents, opt, selected, toggleOption }')
q-item(v-bind='itemProps', v-on='itemEvents')
q-item-section(side)
q-toggle(
:value='selected'
@input='toggleOption(opt)'
:model-value='selected'
@update:model-value='toggleOption(opt)'
color='primary'
checked-icon='las la-check'
unchecked-icon='las la-times'
......@@ -273,8 +282,8 @@ q-layout(view='hHh lpR fFf', container)
q-item-label {{opt.title}}
q-item-section(side)
q-toggle(
:value='selected'
@input='toggleOption(opt)'
:model-value='selected'
@update:model-value='toggleOption(opt)'
color='primary'
checked-icon='las la-check'
unchecked-icon='las la-times'
......@@ -292,7 +301,7 @@ q-layout(view='hHh lpR fFf', container)
option-label='name'
multiple
behavior='dialog'
:display-value='t(`admin.groups.selectedLocales`, rule.locales.length, { count: rule.locales.length, locale: rule.locales.length === 1 ? rule.locales[0].toUpperCase() : `` })'
:display-value='t(`admin.groups.selectedLocales`, { n: rule.locales.length > 0 ? rule.locales[0].toUpperCase() : rule.locales.length }, rule.locales.length)'
)
template(v-slot:option='{ itemProps, opt, selected, toggleOption }')
q-item(v-bind='itemProps')
......@@ -350,7 +359,7 @@ q-layout(view='hHh lpR fFf', container)
flat
color='grey'
type='a'
href='https://docs.js.wiki/admin/groups#permissions'
:href='siteStore.docsBase + `/admin/groups#permissions`'
target='_blank'
)
template(v-for='(perm, idx) of permissions', :key='perm.permission')
......@@ -388,7 +397,7 @@ q-layout(view='hHh lpR fFf', container)
flat
color='grey'
type='a'
href='https://docs.js.wiki/admin/groups#users'
:href='siteStore.docsBase + `/admin/groups#users`'
target='_blank'
)
q-input.denser.fill-outline.q-mr-sm(
......@@ -504,6 +513,7 @@ import { computed, onMounted, reactive, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useAdminStore } from 'src/stores/admin'
import { useSiteStore } from 'src/stores/site'
// QUASAR
......@@ -512,6 +522,7 @@ const $q = useQuasar()
// STORES
const adminStore = useAdminStore()
const siteStore = useSiteStore()
// ROUTER
......@@ -693,7 +704,7 @@ const rules = [
},
{
permission: 'read:source',
title: 'View Pages Source',
title: 'View Page Source',
hint: 'Can view pages source.',
warning: false,
restrictedForSystem: false,
......@@ -802,6 +813,14 @@ function getRuleModeColor (mode) {
})[mode]
}
function getRuleModeBgColor (mode) {
return ({
DENY: 'negative',
ALLOW: 'positive',
FORCEALLOW: 'blue'
})[mode]
}
function getRuleModeClass (mode) {
return 'is-' + mode.toLowerCase()
}
......@@ -913,7 +932,8 @@ function exportRules () {
message: t('admin.groups.exportRulesNoneError')
})
}
exportFile('rules.json', JSON.stringify(state.group.rules, null, 2), { mimeType: 'application/json;charset=UTF-8' })
const rules = state.group.rules.map(({ __typename, ...r }) => r)
exportFile('rules.json', JSON.stringify(rules, null, 2), { mimeType: 'application/json;charset=UTF-8' })
}
async function importRules () {
......
......@@ -149,9 +149,12 @@
no-caps
@click='createPage'
)
q-btn.acrylic-btn.q-ml-sm(
q-btn-group.q-ml-sm(
v-else
flat
)
q-btn.acrylic-btn(
flat
icon='las la-check'
color='positive'
:label='t(`common.actions.saveChanges`)'
......@@ -161,7 +164,16 @@
@click.exact='saveChanges(false)'
@click.ctrl.exact='saveChanges(true)'
)
q-tooltip {{ t(`editor.saveAndCloseTip`) }}
q-separator(vertical, dark)
q-btn.acrylic-btn(
flat
icon='las la-check-double'
color='positive'
:aria-label='t(`common.actions.saveAndClose`)'
:disabled='!editorStore.hasPendingChanges'
@click='saveChanges(true)'
)
q-tooltip {{ t(`common.actions.saveAndClose`) }}
template(v-else-if='userStore.can(`edit:pages`)')
q-btn.acrylic-btn.q-ml-md(
flat
......
......@@ -19,6 +19,7 @@ q-menu.translucent-menu(
)
blueprint-icon(icon='markdown')
q-item-section.q-pr-sm New Markdown Page
template(v-if='flagsStore.experimental')
q-item(
clickable
@click='create(`asciidoc`)'
......@@ -26,7 +27,6 @@ q-menu.translucent-menu(
)
blueprint-icon(icon='asciidoc')
q-item-section.q-pr-sm New AsciiDoc Page
template(v-if='flagsStore.experimental')
q-item(
clickable
@click='create(`channel`)'
......
......@@ -62,7 +62,7 @@ q-page.admin-locale
)
q-separator.q-my-sm(inset)
q-item(tag='label')
blueprint-icon(icon='unit')
blueprint-icon(icon='close-pane')
q-item-section
q-item-label {{t(`admin.locale.forcePrefix`)}}
q-item-label(caption) {{t(`admin.locale.forcePrefixHint`)}}
......@@ -113,8 +113,6 @@ q-page.admin-locale
import gql from 'graphql-tag'
import { cloneDeep, sortBy } from 'lodash-es'
import LocaleInstallDialog from '../components/LocaleInstallDialog.vue'
import { useI18n } from 'vue-i18n'
import { useMeta, useQuasar } from 'quasar'
import { computed, onMounted, reactive, watch } from 'vue'
......@@ -164,14 +162,6 @@ watch(() => state.selectedLocale, (newValue) => {
// METHODS
function installNewLocale () {
$q.dialog({
component: LocaleInstallDialog
}).onOk(() => {
this.load()
})
}
async function load () {
state.loading++
$q.loading.show()
......@@ -218,46 +208,6 @@ async function load () {
state.loading--
}
async function download (lc) {
lc.isDownloading = true
const respRaw = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation downloadLocale ($locale: String!) {
localization {
downloadLocale (locale: $locale) {
responseResult {
succeeded
errorCode
slug
message
}
}
}
}
`,
variables: {
locale: lc.code
}
})
const resp = respRaw?.data?.localization?.downloadLocale?.responseResult || {}
if (resp.succeeded) {
lc.isDownloading = false
lc.isInstalled = true
lc.updatedAt = new Date().toISOString()
lc.installDate = lc.updatedAt
$q.notify({
message: `Locale ${lc.name} has been installed successfully.`,
type: 'positive'
})
} else {
$q.notify({
type: 'negative',
message: resp.message
})
}
state.isDownloading = false
}
async function save () {
state.loading = true
const respRaw = await APOLLO_CLIENT.mutate({
......
......@@ -30,7 +30,7 @@ q-page.admin-terminal
flat
color='grey'
:aria-label='t(`common.actions.viewDocs`)'
:href='siteStore.docsBase + `/admin/scheduler`'
:href='siteStore.docsBase + `/system/scheduler`'
target='_blank'
type='a'
)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment