Skip to content

Commit

Permalink
use table for page list
Browse files Browse the repository at this point in the history
  • Loading branch information
TheHadiAhmadi committed Sep 11, 2024
1 parent 75f9f77 commit 628764a
Show file tree
Hide file tree
Showing 18 changed files with 292 additions and 51 deletions.
23 changes: 21 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"license": "ISC",
"description": "",
"dependencies": {
"@faker-js/faker": "^9.0.0",
"cookie-parser": "^1.4.6",
"dotenv": "^16.4.5",
"express": "^4.19.2",
Expand Down
Binary file added public/images/placeholder.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 8 additions & 11 deletions public/js/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ const actions = {
},
'change-dynamic-page-content'(el) {
const view = new URL(window.location.href).searchParams.get('view') ?? ''
reload('/admin?slug=' + encodeURIComponent(el.value) + (view ? '&view=' + view : ''))
reload('/admin?' + el.value + (view ? '&view=' + view : ''))
},
async 'module-add-field-choose-type'(el) {
const value = el.dataset.value
Expand Down Expand Up @@ -233,24 +233,21 @@ const actions = {
hydrate(el)
})
},
'open-user-edit'(el) {
const userId = el.dataset.id

reload('?view=settings.users.update&id=' + userId)
},
'open-user-delete'(el) {
openConfirm({
title: 'Are you sure?',
description: 'Are you sure to remove this user?',
action: 'user.delete',
id: el.dataset.id
})
// reload('?view=user-edit&id=' + userId)
},
'open-role-edit'(el) {
const roleId = el.dataset.id

reload('?view=settings.roles.update&id=' + roleId)
'open-page-delete'(el) {
openConfirm({
title: 'Are you sure?',
description: 'Are you sure to remove this page?',
action: 'page.delete',
id: el.dataset.id
})
},
'open-role-delete'(el) {
openConfirm({
Expand Down
2 changes: 1 addition & 1 deletion public/js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export async function reloadIframe() {
return reload(window.location.href)
}

const res = await fetch(new URL(window.location.href).searchParams.get('slug') + '?mode=preview').then(res => res.text())
const res = await fetch(iframeElement.getAttribute('src')).then(res => res.text())

const template = document.createElement('template')
template.innerHTML = res
Expand Down
14 changes: 14 additions & 0 deletions public/js/hydrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ import { CodeEditor } from "./code-editor.js"

const components = Components()

function BlockPreview(el) {
console.log('block preview')
const darkBtn = el.querySelector('[data-preview-action="dark"]')
const lightBtn = el.querySelector('[data-preview-action="light"]')
const desktopBtn = el.querySelector('[data-preview-action="desktop"]')
const mobileBtn = el.querySelector('[data-preview-action="mobile"]')

const iframe = el.querySelector('iframe')

// set iframe src based on state...

}

components.register('block-preview', BlockPreview)
components.register('form', Form)
components.register('checkbox', FormCheckbox)
components.register('json', FormJson)
Expand Down
28 changes: 28 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LoginPage } from './pages/login.js'
import { setupCms} from '../services/setup.js'
import hbs from 'handlebars'
import path from 'node:path'
import { fakeValue} from './helpers.js'
import { fileURLToPath } from 'url';
import { exportSiteController } from './controllers/export.js'
import { loginController, logoutController } from './controllers/login.js'
Expand All @@ -13,6 +14,7 @@ import { fileUploadController } from './controllers/file.js'
import { publishController } from './controllers/publish.js'
import { contextMiddleware } from './middlewares/context.js'
import { setDb } from '../services/db.js'
import layouts from './layouts.js';

// Get the directory of the current file
const __dirname = path.dirname(fileURLToPath(import.meta.url));
Expand All @@ -32,6 +34,10 @@ export function createApp({functions, db}) {
// File upload
app.use('/files', express.static('./uploads'))
app.get('/files/:name', (req, res) => {
console.log('files name: ', req.params.name)
if(req.params.name === 'placeholder') {
return res.sendFile(path.resolve(__dirname, '../public', 'images', 'placeholder.jpg'))
}
res.sendFile(path.resolve('./uploads/' + req.params.name.split('.')[0]))
})

Expand Down Expand Up @@ -112,6 +118,28 @@ export function createApp({functions, db}) {
app.post('/api/logout', logoutController)
app.post('/api/publish', publishController)
app.post('/api/export', exportSiteController)

app.get('/preview/:id', async (req, res) => {
const block = await db('blocks').query().filter('id', '=', req.params.id).first()

const props = {}
for(let prop of block.props ?? []) {
props[prop.slug] = await fakeValue(prop)
}

const settings = await db('settings').query().first() ?? {}
console.log(props)
const rendered = hbs.compile(block.template)(props)
return res.end(layouts.default({
head: settings.head,
mode: 'view',
tailwind: JSON.stringify({darkMode: 'class'}),
dir: 'ltr',
theme: 'light',
body: rendered
}))
})

app.get('/*', renderPageController)

app.start = (port) => {
Expand Down
54 changes: 54 additions & 0 deletions src/handlers/page.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,55 @@
import { getPageSlug, getUrl } from "#helpers"
import { db } from "#services"
import { DataTable, getDataTableItems } from "../pages/dataTable.js"

const pageListFields = [
{ label: "Name", slug: "name", type: 'input', default: true, },
{ label: "Slug", slug: "slug", type: 'input', default: true },
{ label: "Dynamic", slug: "dynamic", type: 'checkbox' },
{ label: "Collection", slug: "collectionId", type: 'collection' }
]

export async function PagesDataTable({page = 1, perPage = 10, filters = [], selectable = false}) {
const query = db('pages').query()

const items = await getDataTableItems({
page,
perPage,
query,
fields: pageListFields,
filters,
expandRelations: true
})

return DataTable({
selectable,
filters,
handler: 'page.loadTable',
fields: pageListFields,
items,
actions(item) {
return [
{
href: getUrl({view: 'iframe', id: item.id, contentId: ''}),
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h8.925l-2 2H5v14h14v-6.95l2-2V19q0 .825-.587 1.413T19 21zm4-6v-4.25l9.175-9.175q.3-.3.675-.45t.75-.15q.4 0 .763.15t.662.45L22.425 3q.275.3.425.663T23 4.4t-.137.738t-.438.662L13.25 15zM21.025 4.4l-1.4-1.4zM11 13h1.4l5.8-5.8l-.7-.7l-.725-.7L11 11.575zm6.5-6.5l-.725-.7zl.7.7z"/></svg>`,
action: `open-page-edit`
},
{
href: getUrl({view: 'pages.update', id: item.id, back: encodeURIComponent(getUrl({view: 'pages.list'}))}),
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="m9.25 22l-.4-3.2q-.325-.125-.612-.3t-.563-.375L4.7 19.375l-2.75-4.75l2.575-1.95Q4.5 12.5 4.5 12.338v-.675q0-.163.025-.338L1.95 9.375l2.75-4.75l2.975 1.25q.275-.2.575-.375t.6-.3l.4-3.2h5.5l.4 3.2q.325.125.613.3t.562.375l2.975-1.25l2.75 4.75l-2.575 1.95q.025.175.025.338v.674q0 .163-.05.338l2.575 1.95l-2.75 4.75l-2.95-1.25q-.275.2-.575.375t-.6.3l-.4 3.2zm2.8-6.5q1.45 0 2.475-1.025T15.55 12t-1.025-2.475T12.05 8.5q-1.475 0-2.488 1.025T8.55 12t1.013 2.475T12.05 15.5"/></svg>`,
color: 'primary',
action: `open-page-settings`
},
{
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z"/></svg>`,
color: 'danger',
action: 'open-page-delete'
},
]
}
})

}

export default {
async create(body) {
Expand Down Expand Up @@ -43,5 +94,8 @@ export default {
return {
redirect: '/admin'
}
},
async loadTable(body) {
return PagesDataTable(body)
}
}
27 changes: 18 additions & 9 deletions src/handlers/role.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getUrl } from "#helpers"
import { db } from "#services"
import { DataTable, getDataTableItems } from "../pages/dataTable.js"

Expand Down Expand Up @@ -148,15 +149,23 @@ export async function RolesDataTable({filters = [], perPage = 10, page = 1, sele
handler: 'role.loadTable',
fields: roleTableFields,
items,
actions: [
{
icon: true,
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h8.925l-2 2H5v14h14v-6.95l2-2V19q0 .825-.587 1.413T19 21zm4-6v-4.25l9.175-9.175q.3-.3.675-.45t.75-.15q.4 0 .763.15t.662.45L22.425 3q.275.3.425.663T23 4.4t-.137.738t-.438.662L13.25 15zM21.025 4.4l-1.4-1.4zM11 13h1.4l5.8-5.8l-.7-.7l-.725-.7L11 11.575zm6.5-6.5l-.725-.7zl.7.7z"/></svg>`,
color: 'primary',
action: `open-role-edit`
},
{ icon: true, text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z"/></svg>`, color: 'danger', action: 'open-role-delete' },
]
actions(item) {
return [
{
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h8.925l-2 2H5v14h14v-6.95l2-2V19q0 .825-.587 1.413T19 21zm4-6v-4.25l9.175-9.175q.3-.3.675-.45t.75-.15q.4 0 .763.15t.662.45L22.425 3q.275.3.425.663T23 4.4t-.137.738t-.438.662L13.25 15zM21.025 4.4l-1.4-1.4zM11 13h1.4l5.8-5.8l-.7-.7l-.725-.7L11 11.575zm6.5-6.5l-.725-.7zl.7.7z"/></svg>`,
color: 'primary',
href: getUrl({view: 'settings.roles.update', id: item.id})
},
{
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z"/></svg>`,
color: 'danger',
dataset: {
id: item.id
},
action: 'open-role-delete'
},
]
}
})

}
Expand Down
27 changes: 18 additions & 9 deletions src/handlers/user.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getUrl } from "#helpers"
import { db } from "#services"
import { DataTable, getDataTableItems } from "../pages/dataTable.js"

Expand Down Expand Up @@ -75,15 +76,23 @@ export async function UsersDataTable({filters = [], perPage = 10, page = 1, sele
handler: 'user.loadTable',
fields: userFields,
items,
actions: [
{
icon: true,
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h8.925l-2 2H5v14h14v-6.95l2-2V19q0 .825-.587 1.413T19 21zm4-6v-4.25l9.175-9.175q.3-.3.675-.45t.75-.15q.4 0 .763.15t.662.45L22.425 3q.275.3.425.663T23 4.4t-.137.738t-.438.662L13.25 15zM21.025 4.4l-1.4-1.4zM11 13h1.4l5.8-5.8l-.7-.7l-.725-.7L11 11.575zm6.5-6.5l-.725-.7zl.7.7z"/></svg>`,
color: 'primary',
action: `open-user-edit`
},
{ icon: true, text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z"/></svg>`, color: 'danger', action: 'open-user-delete' },
]
actions(item) {
return [
{
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h8.925l-2 2H5v14h14v-6.95l2-2V19q0 .825-.587 1.413T19 21zm4-6v-4.25l9.175-9.175q.3-.3.675-.45t.75-.15q.4 0 .763.15t.662.45L22.425 3q.275.3.425.663T23 4.4t-.137.738t-.438.662L13.25 15zM21.025 4.4l-1.4-1.4zM11 13h1.4l5.8-5.8l-.7-.7l-.725-.7L11 11.575zm6.5-6.5l-.725-.7zl.7.7z"/></svg>`,
color: 'primary',
href: getUrl({view: 'settings.users.update', id: item.id})
},
{
text: `<svg data-icon xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z"/></svg>`,
color: 'danger',
dataset: {
id: item.id
},
action: 'open-user-delete'
},
]
}
})

}
Expand Down
53 changes: 53 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import hbs from 'handlebars'
import { join } from 'path'
import {readFile} from 'fs/promises'
import { OpenAI } from 'openai'
import { faker } from "@faker-js/faker";

export async function fileToBase64(filePath) {
try {
Expand Down Expand Up @@ -165,3 +166,55 @@ export function getValue(option) {
export function isSelected(option) {
return typeof option === 'object' && option.selected
}

export async function fakeValue(field) {
switch (field.type) {
case 'input':
if (field.input_type === 'email') {
return faker.internet.email();
}
if (field.input_type === 'number') {
return faker.number.int({ min: 0, max: 1000 });
}
const len = faker.number.int({ max: 5 })

return faker.lorem.words(len); // Default for text inputs
case 'textarea':
return faker.lorem.paragraphs(2);
case 'select':
let length = field.items.length
const random = faker.number.int({ max: length })
console.log(random, field.items)
return field.items[random]
case 'checkbox':
return faker.datatype.boolean();
case 'file':
if(field.multiple) {
return [{id: 'placeholder'},{id: 'placeholder'},{id: 'placeholder'},{id: 'placeholder'}]
}
return {id: 'placeholder'}
// return faker.system.fileName(); // This could be more sophisticated depending on the use case
case 'relation':
const data = await db('contents').query().filter('_type', '=', field.collectionId).paginate(1, 10)
// return
return field.multiple ? data.data.slice(5) : data.data[0]; // Simulating an ID or multiple IDs

case 'rich-text':
return faker.lorem.paragraphs(2);
case 'collection':
return []
// return field.items && field.items.length > 0 ? faker.random.arrayElement(field.items.map(item => item.value)) : '';
case 'function':
return null;
// return field.items && field.items.length > 0 ? faker.random.arrayElement(field.items.map(item => item.value)) : '';
case 'color':
return faker.color.rgb(); // Generate a random RGB color
case 'date':
return faker.date.recent().toISOString(); // Generate a recent date in ISO format
case 'hidden':
return ''; // Typically hidden fields don't need fake data
default:
return ''; // Default case for any unspecified field types
}
}

Loading

0 comments on commit 628764a

Please sign in to comment.