1
0
Fork 0
mirror of https://github.com/codex-team/codex.docs.git synced 2025-08-02 03:55:23 +02:00

Typescript rewrite (#147)

* Updated highlight.js

* Update .codexdocsrc.sample

remove undefined page for a fresh new install

* backend rewritten in TS

* test -> TS, .added dockerignore, bug fixed

* Removed compiled js files, eslint codex/ts added

* fixed jsdocs warning, leaving editor confirmation

* use path.resolve for DB paths

* db drives updated + fixed User model

* redundant cleared + style fixed

* explicit type fixing

* fixing testing code

* added body block type

* compiled JS files -> dist, fixed compiling errors

* fixed compiling error, re-organized ts source code

* updated Dockerfile

* fixed link to parent page

* up nodejs version

* fix package name

* fix deps

Co-authored-by: nvc8996 <nvc.8996@gmail.com>
Co-authored-by: Taly <vitalik7tv@yandex.ru>
This commit is contained in:
Nikita Melnikov 2022-03-05 22:57:23 +04:00 committed by GitHub
parent 059cfb96f9
commit 34514761f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
99 changed files with 3817 additions and 2249 deletions

View file

@ -0,0 +1,16 @@
{% extends 'layout.twig' %}
{% block body %}
<form class="auth-form" method="post" action="/auth">
<h1>
┬┴┬┴┤ ͜ʖ ͡°) ├┬┴┬┴
</h1>
<p>
Enter a password to access pages editing
</p>
<input type="hidden" name="_csrf" value={{ csrfToken }}>
<input type="password" name="password" placeholder="Password">
<input type="submit" value="Login">
</form>
{% endblock %}

View file

@ -0,0 +1,41 @@
<div class="docs-aside-toggler" onclick="document.querySelector('.docs-aside').classList.toggle('docs-aside--toggled')">
{{ svg('menu') }} Table of contents
</div>
<div class="docs-aside">
{% for firstLevelPage in menu %}
<section class="docs-aside__section">
<a
{% if page is defined and page._id == firstLevelPage._id%}
class="docs-aside__section-title docs-aside__current"
{% else %}
class="docs-aside__section-title"
{% endif %}
{% if firstLevelPage.uri %}
href="/{{ firstLevelPage.uri }}"
{% else %}
href="/page/{{ firstLevelPage._id }}"
{% endif %}>
{{ firstLevelPage.title | striptags }}
</a>
{% if firstLevelPage.children is not empty %}
<ul class="docs-aside__section-list">
{% for child in firstLevelPage.children %}
<li>
<a
{% if page is defined and page._id == child._id %}
class="docs-aside__current"
{% endif %}
{% if child.uri %}
href="/{{ child.uri }}"
{% else %}
href="/page/{{ child._id }}"
{% endif %}>
{{ child.title | striptags }}
</a>
</li>
{% endfor %}
</ul>
{% endif %}
</section>
{% endfor %}
</div>

View file

@ -0,0 +1,27 @@
<header class="docs-header">
<a href="/" class="docs-header__logo">
{{ config.title | striptags }}
</a>
<ul class="docs-header__menu">
{% if isAuthorized == true %}
<li class="docs-header__menu-add">
<a class="docs-header__button" href="/page/new">
{{ svg('plus') }}
Add Page
</a>
</li>
{% endif %}
{% for option in config.menu %}
<li>
<a
{% if option.uri %}
href="{{ option.uri }}"
{% else %}
href="/page/{{ option._id }}"
{% endif %}>
{{ option.title | striptags }}
</a>
</li>
{% endfor %}
</ul>
</header>

View file

@ -0,0 +1,7 @@
{% extends 'layout.twig' %}
{% block body %}
<h1>{{message}}</h1>
<h2>{{error.status}}</h2>
<pre>{{error.stack}}</pre>
{% endblock %}

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ (page.title ?: config.title) | striptags }}</title>
<link rel="stylesheet" href="/dist/main.css" />
<meta property="og:type" content="article" />
<meta property="og:title" content="{{ page.title | striptags }}" />
<meta property="article:modified_time" content="{{ (page.body.time / 1000) | date("c") }}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="icon" type="image/png" href="/favicon.png">
</head>
<script>
window.config = {
misprintsChatId: "{{ config.misprintsChatId }}"
};
</script>
<body>
{% include "components/header.twig" with res.locals.isAuthorized %}
<div class="docs">
<aside class="docs__aside">
{% include "components/aside.twig" %}
</aside>
<div class="docs__content">
<div class="docs__content-inner">
{% block body %}{% endblock %}
</div>
</div>
</div>
<script src="/dist/main.bundle.js"></script>
{% if config.yandexMetrikaId is not empty %}
<script type="text/javascript" >
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym({{ config.yandexMetrikaId }}, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true
});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/{{ config.yandexMetrikaId }}" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
{% endif %}
</body>
</html>

View file

@ -0,0 +1,12 @@
<div class="block-checklist">
{% for item in items %}
<div class="block-checklist__item">
{% if item.checked %}
<span class="block-checklist__item-checkbox block-checklist__item-checkbox--checked"></span>
{% else %}
<span class="block-checklist__item-checkbox"></span>
{% endif %}
<div class="block-checklist__item-text">{{ item.text }}</div>
</div>
{% endfor %}
</div>

View file

@ -0,0 +1,4 @@
<div class="block-code">
<div class="block-code__content">{{ code|escape }}</div>
</div>

View file

@ -0,0 +1 @@
<div class="block-delimiter"></div>

View file

@ -0,0 +1,12 @@
<figure class="block-embed">
<iframe
class="block-embed__iframe"
src="{{ embed }}"
frameborder="0"
></iframe>
{% if caption %}
<footer class="block-iframe__caption">
{{ caption }}
</footer>
{% endif %}
</figure>

View file

@ -0,0 +1,7 @@
<a name="{{ text | urlify }}" style="display: inline-block; position: absolute; margin-top: -20px;"></a>
<h{{ level }} class="block-header block-header--{{ level }} block-header--anchor">
<a href="#{{ text | urlify }}">
{{ text }}
</a>
</h{{ level }}>

View file

@ -0,0 +1,31 @@
{% set classes = ['block-image__content'] %}
{% if withBorder %}
{% set classes = classes|merge(['block-image__content--bordered']) %}
{% endif %}
{% if stretched %}
{% set classes = classes|merge(['block-image__content--stretched']) %}
{% endif %}
{% if withBackground %}
{% set classes = classes|merge(['block-image__content--with-background']) %}
{% endif %}
<figure class="block-image">
<div class="{{ classes.join(' ') }}">
{% if file.mime and file.mime == 'video/mp4' %}
<video autoplay loop muted playsinline>
<source src="{{ file.url }}" type="video/mp4">
</video>
{% else %}
<img src="{{ file.url }}" alt="{{ caption ? caption | striptags : '' }}">
{% endif %}
</div>
{% if caption %}
<footer class="block-image__caption">
{{ caption }}
</footer>
{% endif %}
</figure>

View file

@ -0,0 +1,17 @@
<a class="block-link" href="{{ link }}" target="_blank" rel="nofollow">
{% if meta.image.url %}
<img class="block-link__image" src="{{ meta.image.url }}">
{% endif %}
<div class="block-link__title">
{{ meta.title }}
</div>
<div class="block-link__description">
{{ meta.description }}
</div>
<span class="block-link__domain">
{{ parseLink(link).hostname }}
</span>
</a>

View file

@ -0,0 +1,13 @@
{% set tag = 'ul' %}
{% if style == 'ordered' %}
{% set tag = 'ol' %}
{% endif %}
<{{ tag }} class="block-list block-list--{{ style }}">
{% for item in items %}
<li>
{{ item }}
</li>
{% endfor %}
</{{ tag }}>

View file

@ -0,0 +1,3 @@
<p class="block-paragraph">
{{ text }}
</p>

View file

@ -0,0 +1 @@
{{ html }}

View file

@ -0,0 +1,11 @@
<table class="block-table">
{% for row in content %}
<tr>
{% for cell in row %}
<td>
{{ cell }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>

View file

@ -0,0 +1,13 @@
<div class="block-warning">
<div class="block-warning__icon">
☝️
</div>
{% if title is not empty %}
<div class="block-warning__title">
{{ title }}
</div>
{% endif %}
<div class="block-warning__message">
{{ message }}
</div>
</div>

View file

@ -0,0 +1,67 @@
{% extends 'layout.twig' %}
{% block body %}
<style>
.docs-header__button {
visibility: hidden;
}
</style>
<section data-module="writing">
<textarea name="module-settings" hidden>
{
"page": {{ page | json_encode | escape }}
}
</textarea>
<header class="writing-header">
<span class="writing-header__left">
<span>
New Page at the
{% set currentPageId = 0 %}
{% if page is not empty %}
{% set currentPageId = page._id %}
{% endif %}
<select name="parent">
<option value="0">Root</option>
{% for _page in pagesAvailable %}
{% if _page._id != currentPageId %}
<option value="{{ _page._id }}" {{ page is not empty and page._parent == _page._id ? 'selected' : ''}}>
{% if _page._parent != "0" %}
&nbsp;
&nbsp;
{% endif %}
{{ _page.title }}
</option>
{% endif %}
{% endfor %}
</select>
</span>
{% if parentsChildrenOrdered is not empty %}
<span>
Put Above
<select name="above">
<option value="0">—</option>
{% for _page in parentsChildrenOrdered %}
<option value="{{ _page._id }}">{{ _page.title }}</option>
{% endfor %}
</select>
</span>
{% endif %}
</span>
{% if page is not empty %}
<p><input type="text" class="uri-input" name="uri-input" placeholder="URI (Optional)" value="{{ page.uri }}"></p>
{% endif %}
</header>
<div class="writing-editor">
<div id="editorjs"></div>
</div>
<div class="writing-buttons">
<span class="writing-header__save" name="js-submit-save">Save</span>
{% if page._id is not empty %}
<span class="writing-buttons__remove" name="js-submit-remove">Remove</span>
{% endif %}
</div>
</section>
{% endblock %}

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html style="height: 100%">
<head>
<title>{{ config.title }}</title>
<link rel="stylesheet" href="/dist/main.css" />
<link rel="preload" href="{{ config.landingFrameSrc }}" as="document">
<link rel="icon" type="image/png" href="/favicon.png?v=2">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta property="og:title" content="{{ config.title }}" />
<meta property="og:site_name" content="{{ config.title }}" />
<meta name="description" property="og:description" content="{{ config.description }}">
</head>
<body class="landing-body">
{% include "components/header.twig" %}
<div class="landing-loader" id="frame-loader">
{{ svg('loader') }}
</div>
<iframe class="landing-frame" src="{{ config.landingFrameSrc }}" seamless frameborder="0" onload="this.style.opacity = 1; setTimeout(document.getElementById('frame-loader').remove(), 500)"></iframe>
{% if config.yandexMetrikaId is not empty %}
<script type="text/javascript" >
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym({{ config.yandexMetrikaId }}, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true
});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/{{ config.yandexMetrikaId }}" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
{% endif %}
</body>
</html>

View file

@ -0,0 +1,48 @@
{% extends 'layout.twig' %}
{% block body %}
<article class="page" data-module="page">
<header class="page__header">
<a href="/" class="page__header-nav">
Documentation
</a>
{% if page._parent %}
<a class="page__header-nav"
{% if pageParent.uri %}
href="/{{ pageParent.uri }}"
{% else %}
href="/page/{{ pageParent._id }}"
{% endif %}>
{{ pageParent.title }}
</a>
{% endif %}
<time class="page__header-time">
Last edit {{ (page.body.time / 1000) | date("M d Y") }}
{% if isAuthorized == true %}
<a href="/page/edit/{{ page._id }}" class="page__header-button">
Edit
</a>
{% endif %}
</time>
</header>
<h1 class="page__title">
{{ page.title }}
</h1>
{% if (config.carbon and config.carbon.placement and config.carbon.serve) %}
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve={{ config.carbon.serve }}&placement={{ config.carbon.placement }}" id="_carbonads_js"></script>
{% endif %}
<section class="page__content">
{% for block in page.body.blocks %}
{# Skip first header, because it is already showed as a Title #}
{% if not (loop.first and block.type == 'header') %}
{% if block.type in ['paragraph', 'header', 'image', 'code', 'list', 'delimiter', 'table', 'warning', 'checklist', 'linkTool', 'raw', 'embed'] %}
{% include './blocks/' ~ block.type ~ '.twig' with block.data %}
{% endif %}
{% endif %}
{% endfor %}
</section>
<footer>
</footer>
</article>
{% endblock %}