Init part 3
This commit is contained in:
parent
635ec65d07
commit
ce88550539
45 changed files with 4124 additions and 0 deletions
20
.checkout/.env
Normal file
20
.checkout/.env
Normal file
|
@ -0,0 +1,20 @@
|
|||
# In all environments, the following files are loaded if they exist,
|
||||
# the latter taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
# https://symfony.com/doc/current/configuration/secrets.html
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_SECRET=5d752842d639735b4175d1abd3d86748
|
||||
###< symfony/framework-bundle ###
|
17
.checkout/.gitignore
vendored
Normal file
17
.checkout/.gitignore
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/config/secrets/prod/prod.decrypt.private.php
|
||||
/public/bundles/
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> symfony/webpack-encore-bundle ###
|
||||
/node_modules/
|
||||
/public/build/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
###< symfony/webpack-encore-bundle ###
|
7
.checkout/assets/app.ts
Normal file
7
.checkout/assets/app.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import './styles/app.scss';
|
||||
// start the Stimulus application
|
||||
import './bootstrap';
|
||||
|
||||
import cards_controller from './controllers/cards_controller';
|
||||
|
||||
cards_controller.bindAllCardDragAndDropEvents();
|
8
.checkout/assets/bootstrap.ts
Normal file
8
.checkout/assets/bootstrap.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { startStimulusApp } from '@symfony/stimulus-bridge';
|
||||
|
||||
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
||||
export const app = startStimulusApp(require.context(
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.[jt]sx?$/
|
||||
));
|
4
.checkout/assets/controllers.json
Normal file
4
.checkout/assets/controllers.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"controllers": [],
|
||||
"entrypoints": []
|
||||
}
|
58
.checkout/assets/controllers/card_controller.js
Normal file
58
.checkout/assets/controllers/card_controller.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
import cards_controller from './cards_controller';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['value', 'textarea', 'save', 'revert', 'edit', 'delete']
|
||||
edit_card(){
|
||||
this.textareaTarget.style.display = 'block'
|
||||
this.saveTarget.style.display = 'block'
|
||||
this.revertTarget.style.display = 'block'
|
||||
this.valueTarget.style.display = 'none'
|
||||
this.editTarget.style.display = 'none'
|
||||
this.deleteTarget.style.display = 'none'
|
||||
this.textareaTarget.value = this.valueTarget.innerText
|
||||
this.element.draggable = false;
|
||||
}
|
||||
edit_card_save(){
|
||||
var value = this.textareaTarget.value.replace(/(?:\r\n|\r|\n)/g, '%5Cr%5Cn');
|
||||
console.log(this.textareaTarget.value);
|
||||
if(value.length === 0){
|
||||
return
|
||||
}
|
||||
const xhttp = new XMLHttpRequest()
|
||||
xhttp.open("GET", location.origin + `/kanban/api/card/set/value/${this.element.getAttribute('db_id')}/${value}`, true)
|
||||
xhttp.onreadystatechange = (ev) => {
|
||||
if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
|
||||
this.valueTarget.innerText = this.textareaTarget.value;
|
||||
this.valueTarget.style.display = 'block'
|
||||
this.editTarget.style.display = 'block'
|
||||
this.deleteTarget.style.display = 'block'
|
||||
this.textareaTarget.style.display = 'none'
|
||||
this.saveTarget.style.display = 'none'
|
||||
this.revertTarget.style.display = 'none'
|
||||
this.element.draggable = true;
|
||||
}
|
||||
}
|
||||
xhttp.send()
|
||||
|
||||
}
|
||||
edit_card_revert(){
|
||||
this.valueTarget.style.display = 'block'
|
||||
this.editTarget.style.display = 'block'
|
||||
this.deleteTarget.style.display = 'block'
|
||||
this.textareaTarget.style.display = 'none'
|
||||
this.saveTarget.style.display = 'none'
|
||||
this.revertTarget.style.display = 'none'
|
||||
this.element.draggable = true;
|
||||
}
|
||||
delete_card(){
|
||||
const xhttp = new XMLHttpRequest()
|
||||
xhttp.open("GET", location.origin + `/kanban/api/card/delete/${this.element.getAttribute('db_id')}`, true)
|
||||
xhttp.onreadystatechange = (ev) => {
|
||||
if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
|
||||
this.element.remove()
|
||||
}
|
||||
}
|
||||
xhttp.send()
|
||||
}
|
||||
}
|
57
.checkout/assets/controllers/cards_controller.ts
Normal file
57
.checkout/assets/controllers/cards_controller.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
|
||||
|
||||
export default class{
|
||||
static bindAllCardDragAndDropEvents(){
|
||||
var cards = document.getElementsByClassName("card")
|
||||
for (let i = 0; i < cards.length; i++) {
|
||||
cards[i].addEventListener("dragstart", this.onDragStart);
|
||||
var card = cards[i] as HTMLElement
|
||||
card.draggable = true
|
||||
}
|
||||
var cardLists = document.getElementsByClassName("card-list")
|
||||
for (let i = 0; i < cardLists.length; i++) {
|
||||
cardLists[i].addEventListener("drop", this.onDrop)
|
||||
cardLists[i].addEventListener("dragover", this.allowDrop)
|
||||
}
|
||||
}
|
||||
static bindSpecificCardDragAndDropEvents(card){
|
||||
card.addEventListener("dragstart", this.onDragStart)
|
||||
}
|
||||
static onDragStart(event) {
|
||||
event.dataTransfer.clearData();
|
||||
event.dataTransfer.setData("text/plain", event.target.id)
|
||||
}
|
||||
static allowDrop(event) {
|
||||
event.preventDefault()
|
||||
}
|
||||
static onDrop(event) {
|
||||
const data = event.dataTransfer.getData("text")
|
||||
event.preventDefault()
|
||||
const cardlist = event.target.closest(".card-list")
|
||||
const card = document.getElementById(data)
|
||||
const origin_columnId = card.closest(".column").id
|
||||
const target_columnId = cardlist.closest(".column").id
|
||||
const cardId = card.getAttribute("db_id");
|
||||
if(target_columnId == origin_columnId){
|
||||
return
|
||||
}
|
||||
const xhttp = new XMLHttpRequest()
|
||||
const xhttp2 = new XMLHttpRequest()
|
||||
if(target_columnId == "-2"){
|
||||
xhttp2.open("GET", `${location.origin}/kanban/api/card/set/done/${cardId}/true`, true)
|
||||
xhttp2.send()
|
||||
} else if(origin_columnId == "-2"){
|
||||
xhttp2.open("GET", `${location.origin}/kanban/api/card/set/done/${cardId}/false`, true)
|
||||
xhttp2.send()
|
||||
}
|
||||
|
||||
xhttp.open("GET", `${location.origin}/kanban/api/card/move/${cardId}/${target_columnId}`, true)
|
||||
xhttp.onreadystatechange = (ev) => {
|
||||
if (xhttp.readyState !== XMLHttpRequest.DONE || xhttp.status !== 200){
|
||||
return
|
||||
}
|
||||
cardlist.appendChild(card)
|
||||
}
|
||||
xhttp.send()
|
||||
}
|
||||
}
|
27
.checkout/assets/controllers/column_controller.js
Normal file
27
.checkout/assets/controllers/column_controller.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
import cards_controller from './cards_controller';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['value', 'output']
|
||||
create_card(){
|
||||
var value = this.valueTarget.value.replace(/(?:\r\n|\r|\n)/g, '%5Cr%5Cn')
|
||||
if(value.length == 0){
|
||||
return
|
||||
}
|
||||
const xhttp = new XMLHttpRequest()
|
||||
xhttp.open("GET", location.origin + `/kanban/api/card/create/${this.element.id}/${value}`, true)
|
||||
xhttp.onreadystatechange = (ev) => {
|
||||
if (xhttp.readyState === XMLHttpRequest.DONE) {
|
||||
var template = document.createElement('template')
|
||||
var response = xhttp.responseText.trim();
|
||||
response = response.replace(/(?:\\r\\n|\\r|\\n)/g, '<br>\n')
|
||||
template.innerHTML = response
|
||||
const card = template.content.firstChild
|
||||
cards_controller.bindSpecificCardDragAndDropEvents(card)
|
||||
this.outputTarget.appendChild(card)
|
||||
this.valueTarget.value = ""
|
||||
}
|
||||
}
|
||||
xhttp.send()
|
||||
}
|
||||
}
|
11
.checkout/assets/styles/app.scss
Normal file
11
.checkout/assets/styles/app.scss
Normal file
|
@ -0,0 +1,11 @@
|
|||
@import "theme";
|
||||
|
||||
@import "components/wrapper";
|
||||
|
||||
@import "components/column";
|
||||
@import "components/card";
|
||||
|
||||
:root,html,body{
|
||||
margin: 0;
|
||||
height: fit-content;
|
||||
}
|
52
.checkout/assets/styles/components/card.scss
Normal file
52
.checkout/assets/styles/components/card.scss
Normal file
|
@ -0,0 +1,52 @@
|
|||
@import '../theme';
|
||||
|
||||
.card{
|
||||
min-height: 5rem;
|
||||
text-align: left;
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
background: $bg-3;
|
||||
outline: $fg-3 solid 0.1rem;
|
||||
@media (prefers-color-scheme: light) {
|
||||
background: $bga-3;
|
||||
outline-color: $fga-3;
|
||||
}
|
||||
|
||||
.card-button{
|
||||
background: transparent;
|
||||
border: none;
|
||||
float: right;
|
||||
|
||||
color: $fg-4;
|
||||
&:hover{
|
||||
color: $fg-2;
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
color: $fga-5;
|
||||
&:hover{
|
||||
color: $fga-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p{
|
||||
margin: 0;
|
||||
}
|
||||
.card-edit-textarea{
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
height: 7rem;
|
||||
min-height: 7rem;
|
||||
max-height: 15rem;
|
||||
border-radius: 0.5rem;
|
||||
border: none;
|
||||
background: $bg-4;
|
||||
color: $fg-2;
|
||||
@media (prefers-color-scheme: light) {
|
||||
background: $bga-4;
|
||||
color: $fga-2;
|
||||
}
|
||||
}
|
||||
}
|
95
.checkout/assets/styles/components/column.scss
Normal file
95
.checkout/assets/styles/components/column.scss
Normal file
|
@ -0,0 +1,95 @@
|
|||
@import '../theme';
|
||||
|
||||
.column{
|
||||
width: 20rem;
|
||||
min-width: 20rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
background: $bg-2;
|
||||
@media (prefers-color-scheme: light) {
|
||||
background: $bga-2;
|
||||
}
|
||||
border-radius: 0.5rem;
|
||||
.column-title-bar{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
h2{
|
||||
|
||||
}
|
||||
.add-card-button{
|
||||
margin-left: auto;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
background: transparent;
|
||||
color: $fg-2;
|
||||
border: $fg-2 solid 2px;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
&:hover{
|
||||
box-shadow: 0 0 0.5rem 0 $fg-1 ;
|
||||
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
color: $fga-2;
|
||||
border-color: $fga-2;
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0.5rem 0 $fga-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.add-card-textarea-wrapper{
|
||||
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
box-sizing: border-box;
|
||||
.add-card-textarea{
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
height: 7rem;
|
||||
min-height: 7rem;
|
||||
max-height: 15rem;
|
||||
border-radius: 0.5rem;
|
||||
border: none;
|
||||
background: $bg-4;
|
||||
color: $fg-2;
|
||||
@media (prefers-color-scheme: light) {
|
||||
background: $bga-4;
|
||||
color: $fga-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
.card-list-wrapper{
|
||||
padding: 0.5rem;
|
||||
height: 100%;
|
||||
.card-list {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
border-radius: 0.55rem;
|
||||
gap: 0.5rem;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
&:first-of-type, &:last-of-type {
|
||||
.card-list-wrapper > .card-list {
|
||||
background: repeating-linear-gradient(-45deg, $fg-5, $fg-5 0.5rem, $bg-3 0.5rem, $bg-3 1.5rem);
|
||||
@media (prefers-color-scheme: light) {
|
||||
background: repeating-linear-gradient(-45deg, $fga-5, $fga-5 0.5rem, $bga-3 0.5rem, $bga-3 1.5rem);
|
||||
border-color: $fga-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
9
.checkout/assets/styles/components/wrapper.scss
Normal file
9
.checkout/assets/styles/components/wrapper.scss
Normal file
|
@ -0,0 +1,9 @@
|
|||
.wrapper{
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
min-height: calc(100vh - 5rem);
|
||||
}
|
49
.checkout/assets/styles/theme.scss
Normal file
49
.checkout/assets/styles/theme.scss
Normal file
|
@ -0,0 +1,49 @@
|
|||
$white: #fefefe;
|
||||
$light-1: #e0e0e0;
|
||||
$light-2: #c0c0c0;
|
||||
$light-3: #a0a0a0;
|
||||
$light-4: #808080;
|
||||
|
||||
$dark-4: #5c5c5c;
|
||||
$dark-3: #4c4c4c;
|
||||
$dark-2: #3c3c3c;
|
||||
$dark-1: #2c2c2c;
|
||||
$black: #181818;
|
||||
|
||||
//Darkmode (default)
|
||||
$fg-1: $white;
|
||||
$fg-2: $light-1;
|
||||
$fg-3: $light-2;
|
||||
$fg-4: $light-3;
|
||||
$fg-5: $light-4;
|
||||
|
||||
$bg-5: $dark-4;
|
||||
$bg-4: $dark-3;
|
||||
$bg-3: $dark-2;
|
||||
$bg-2: $dark-1;
|
||||
$bg-1: $black;
|
||||
|
||||
//lightmode
|
||||
$fga-1: $black;
|
||||
$fga-2: $dark-1;
|
||||
$fga-3: $dark-2;
|
||||
$fga-4: $dark-3;
|
||||
$fga-5: $dark-4;
|
||||
|
||||
$bga-5: $light-4;
|
||||
$bga-4: $light-3;
|
||||
$bga-3: $light-2;
|
||||
$bga-2: $light-1;
|
||||
$bga-1: $white;
|
||||
|
||||
:root,html{
|
||||
font-family: Helvetica;
|
||||
|
||||
background: $bg-1;
|
||||
color: $fg-2;
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
background: $bga-1;
|
||||
color: $fga-2;
|
||||
}
|
||||
}
|
17
.checkout/bin/console
Normal file
17
.checkout/bin/console
Normal file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
|
||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
||||
}
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
|
||||
return new Application($kernel);
|
||||
};
|
68
.checkout/composer.json
Normal file
68
.checkout/composer.json
Normal file
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"type": "project",
|
||||
"license": "proprietary",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"symfony/console": "6.2.*",
|
||||
"symfony/dotenv": "6.2.*",
|
||||
"symfony/flex": "^2",
|
||||
"symfony/framework-bundle": "6.2.*",
|
||||
"symfony/runtime": "6.2.*",
|
||||
"symfony/twig-bundle": "6.2.*",
|
||||
"symfony/webpack-encore-bundle": "^1.16",
|
||||
"symfony/yaml": "6.2.*",
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"php-http/discovery": true,
|
||||
"symfony/flex": true,
|
||||
"symfony/runtime": true
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
"symfony/polyfill-ctype": "*",
|
||||
"symfony/polyfill-iconv": "*",
|
||||
"symfony/polyfill-php72": "*",
|
||||
"symfony/polyfill-php73": "*",
|
||||
"symfony/polyfill-php74": "*",
|
||||
"symfony/polyfill-php80": "*",
|
||||
"symfony/polyfill-php81": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
]
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
},
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "6.2.*"
|
||||
}
|
||||
}
|
||||
}
|
2899
.checkout/composer.lock
generated
Normal file
2899
.checkout/composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
9
.checkout/config/Config.php
Normal file
9
.checkout/config/Config.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
class Config
|
||||
{
|
||||
public static string $database_host = "localhost";
|
||||
public static string $database_name = "dominik_php_kanban";
|
||||
public static string $database_user = "root";
|
||||
public static string $database_password = "";
|
||||
}
|
7
.checkout/config/bundles.php
Normal file
7
.checkout/config/bundles.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
|
||||
];
|
19
.checkout/config/packages/cache.yaml
Normal file
19
.checkout/config/packages/cache.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
framework:
|
||||
cache:
|
||||
# Unique name of your app: used to compute stable namespaces for cache keys.
|
||||
#prefix_seed: your_vendor_name/app_name
|
||||
|
||||
# The "app" cache stores to the filesystem by default.
|
||||
# The data in this cache should persist between deploys.
|
||||
# Other options include:
|
||||
|
||||
# Redis
|
||||
#app: cache.adapter.redis
|
||||
#default_redis_provider: redis://localhost
|
||||
|
||||
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
|
||||
#app: cache.adapter.apcu
|
||||
|
||||
# Namespaced pools use the above "app" backend by default
|
||||
#pools:
|
||||
#my.dedicated.cache: null
|
25
.checkout/config/packages/framework.yaml
Normal file
25
.checkout/config/packages/framework.yaml
Normal file
|
@ -0,0 +1,25 @@
|
|||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
#csrf_protection: true
|
||||
http_method_override: false
|
||||
handle_all_throwables: true
|
||||
|
||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||
# Remove or comment this section to explicitly disable session support.
|
||||
session:
|
||||
handler_id: null
|
||||
cookie_secure: auto
|
||||
cookie_samesite: lax
|
||||
storage_factory_id: session.storage.factory.native
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
12
.checkout/config/packages/routing.yaml
Normal file
12
.checkout/config/packages/routing.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
framework:
|
||||
router:
|
||||
utf8: true
|
||||
|
||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||
#default_uri: http://localhost
|
||||
|
||||
when@prod:
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: null
|
6
.checkout/config/packages/twig.yaml
Normal file
6
.checkout/config/packages/twig.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
twig:
|
||||
default_path: '%kernel.project_dir%/templates'
|
||||
|
||||
when@test:
|
||||
twig:
|
||||
strict_variables: true
|
45
.checkout/config/packages/webpack_encore.yaml
Normal file
45
.checkout/config/packages/webpack_encore.yaml
Normal file
|
@ -0,0 +1,45 @@
|
|||
webpack_encore:
|
||||
# The path where Encore is building the assets - i.e. Encore.setOutputPath()
|
||||
output_path: '%kernel.project_dir%/public/build'
|
||||
# If multiple builds are defined (as shown below), you can disable the default build:
|
||||
# output_path: false
|
||||
|
||||
# Set attributes that will be rendered on all script and link tags
|
||||
script_attributes:
|
||||
defer: true
|
||||
# Uncomment (also under link_attributes) if using Turbo Drive
|
||||
# https://turbo.hotwired.dev/handbook/drive#reloading-when-assets-change
|
||||
# 'data-turbo-track': reload
|
||||
# link_attributes:
|
||||
# Uncomment if using Turbo Drive
|
||||
# 'data-turbo-track': reload
|
||||
|
||||
# If using Encore.enableIntegrityHashes() and need the crossorigin attribute (default: false, or use 'anonymous' or 'use-credentials')
|
||||
# crossorigin: 'anonymous'
|
||||
|
||||
# Preload all rendered script and link tags automatically via the HTTP/2 Link header
|
||||
# preload: true
|
||||
|
||||
# Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
|
||||
# strict_mode: false
|
||||
|
||||
# If you have multiple builds:
|
||||
# builds:
|
||||
# frontend: '%kernel.project_dir%/public/frontend/build'
|
||||
|
||||
# pass the build name as the 3rd argument to the Twig functions
|
||||
# {{ encore_entry_script_tags('entry1', null, 'frontend') }}
|
||||
|
||||
framework:
|
||||
assets:
|
||||
json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
|
||||
|
||||
#when@prod:
|
||||
# webpack_encore:
|
||||
# # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
|
||||
# # Available in version 1.2
|
||||
# cache: true
|
||||
|
||||
#when@test:
|
||||
# webpack_encore:
|
||||
# strict_mode: false
|
5
.checkout/config/preload.php
Normal file
5
.checkout/config/preload.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
|
||||
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
|
||||
}
|
5
.checkout/config/routes.yaml
Normal file
5
.checkout/config/routes.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
controllers:
|
||||
resource:
|
||||
path: ../src/Controller/
|
||||
namespace: App\Controller
|
||||
type: attribute
|
32
.checkout/config/routes/app_kanban.yaml
Normal file
32
.checkout/config/routes/app_kanban.yaml
Normal file
|
@ -0,0 +1,32 @@
|
|||
app_kanban:
|
||||
path: /kanban
|
||||
controller: App\Controller\Kanban\KanbanController::render_board
|
||||
app_create_card:
|
||||
path: /kanban/api/card/create/{column_id}/{value}
|
||||
controller: App\Controller\Kanban\CardController::create_card
|
||||
requirements:
|
||||
column_id: '-?\d+'
|
||||
value: '.+'
|
||||
app_delete_card:
|
||||
path: /kanban/api/card/delete/{id}
|
||||
controller: App\Controller\Kanban\CardController::delete_card
|
||||
requirements:
|
||||
id: '\d+'
|
||||
app_move_card:
|
||||
path: /kanban/api/card/move/{card_id}/{column_id}
|
||||
controller: App\Controller\Kanban\CardController::move_card
|
||||
requirements:
|
||||
card_id: '\d+'
|
||||
column_id: '-?\d+'
|
||||
app_set_card_value:
|
||||
path: /kanban/api/card/set/value/{card_id}/{value}
|
||||
controller: App\Controller\Kanban\CardController::set_card_value
|
||||
requirements:
|
||||
card_id: '\d+'
|
||||
value: '.+'
|
||||
app_set_card_done:
|
||||
path: /kanban/api/card/set/done/{card_id}/{is_done}
|
||||
controller: App\Controller\Kanban\CardController::set_card_done
|
||||
requirements:
|
||||
card_id: '\d+'
|
||||
is_done: true|false
|
4
.checkout/config/routes/framework.yaml
Normal file
4
.checkout/config/routes/framework.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
when@dev:
|
||||
_errors:
|
||||
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
|
||||
prefix: /_error
|
24
.checkout/config/services.yaml
Normal file
24
.checkout/config/services.yaml
Normal file
|
@ -0,0 +1,24 @@
|
|||
# This file is the entry point to configure your own services.
|
||||
# Files in the packages/ subdirectory configure your dependencies.
|
||||
|
||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||
parameters:
|
||||
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
_defaults:
|
||||
autowire: true # Automatically injects dependencies in your services.
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
resource: '../src/'
|
||||
exclude:
|
||||
- '../src/DependencyInjection/'
|
||||
- '../src/Entity/'
|
||||
- '../src/Kernel.php'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
27
.checkout/package.json
Normal file
27
.checkout/package.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.0",
|
||||
"@babel/preset-env": "^7.16.0",
|
||||
"@hotwired/stimulus": "^3.0.0",
|
||||
"@symfony/stimulus-bridge": "^3.2.0",
|
||||
"@symfony/webpack-encore": "^4.0.0",
|
||||
"core-js": "^3.23.0",
|
||||
"fork-ts-checker-webpack-plugin": "^7.0.0",
|
||||
"regenerator-runtime": "^0.13.9",
|
||||
"sass": "^1.62.1",
|
||||
"sass-loader": "^13.0.0",
|
||||
"ts-loader": "^9.0.0",
|
||||
"typescript": "^5.0.4",
|
||||
"webpack": "^5.74.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-notifier": "^1.15.0"
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev-server": "encore dev-server",
|
||||
"dev": "encore dev",
|
||||
"watch": "encore dev --watch",
|
||||
"build": "encore production --progress"
|
||||
}
|
||||
}
|
9
.checkout/public/index.php
Normal file
9
.checkout/public/index.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
};
|
25
.checkout/schema.sql
Normal file
25
.checkout/schema.sql
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
CREATE TABLE `cards` (
|
||||
`id` bigint(20) UNSIGNED NOT NULL,
|
||||
`value` varchar(256) DEFAULT NULL,
|
||||
`column_id` int(10) UNSIGNED DEFAULT NULL,
|
||||
`is_done` tinyint(1) NOT NULL DEFAULT 0
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `columns` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`title` varchar(64) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
ALTER TABLE `cards`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
ALTER TABLE `columns`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
ALTER TABLE `cards`
|
||||
MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT;
|
||||
|
||||
ALTER TABLE `columns`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
|
||||
COMMIT;
|
0
.checkout/src/Controller/.gitignore
vendored
Normal file
0
.checkout/src/Controller/.gitignore
vendored
Normal file
44
.checkout/src/Controller/Kanban/CardController.php
Normal file
44
.checkout/src/Controller/Kanban/CardController.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Kanban;
|
||||
|
||||
use App\Model\Card;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CardController extends AbstractController
|
||||
{
|
||||
public function create_card(int $column_id, string $value): Response
|
||||
{
|
||||
Card::initPDO();
|
||||
$new_card = Card::createCard($value, $column_id);
|
||||
|
||||
return $this->render('kanban/card.html.twig', [
|
||||
"card" => $new_card
|
||||
]);
|
||||
}
|
||||
public function delete_card(int $id): Response
|
||||
{
|
||||
Card::initPDO();
|
||||
$response_code = $new_card = Card::deleteCard($id) ? 200 : 417;
|
||||
return new Response($response_code);
|
||||
}
|
||||
public function move_card(int $card_id, int $column_id): Response
|
||||
{
|
||||
Card::initPDO();
|
||||
$response_code = Card::moveCard($card_id, $column_id) ? 200 : 417;
|
||||
return new Response($response_code);
|
||||
}
|
||||
public function set_card_value(int $card_id, string $value): Response
|
||||
{
|
||||
Card::initPDO();
|
||||
$response_code = Card::setCardValue($card_id, $value) ? 200 : 417;
|
||||
return new Response($response_code);
|
||||
}
|
||||
public function set_card_done(int $card_id, string $is_done): Response
|
||||
{
|
||||
Card::initPDO();
|
||||
$response_code = Card::setCardDone($card_id, $is_done == "true") ? 200 : 417;
|
||||
return new Response($response_code);
|
||||
}
|
||||
}
|
25
.checkout/src/Controller/Kanban/KanbanController.php
Normal file
25
.checkout/src/Controller/Kanban/KanbanController.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Kanban;
|
||||
|
||||
use App\Model\Card;
|
||||
use App\Model\Column;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class KanbanController extends AbstractController
|
||||
{
|
||||
public function render_board(): Response
|
||||
{
|
||||
Column::initPDO();
|
||||
Card::initPDO();
|
||||
|
||||
$columns = Column::getColumns();
|
||||
$cards = Card::getCards($columns);
|
||||
|
||||
return $this->render('kanban/board.html.twig', [
|
||||
"cards" => $cards,
|
||||
"columns" => $columns
|
||||
]);
|
||||
}
|
||||
}
|
13
.checkout/src/Kernel.php
Normal file
13
.checkout/src/Kernel.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
|
||||
require __DIR__ . '/../config/Config.php';
|
||||
|
||||
class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
}
|
96
.checkout/src/Model/Card.php
Normal file
96
.checkout/src/Model/Card.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
use Config;
|
||||
use PDO;
|
||||
use Symfony\Component\Console\Logger\ConsoleLogger;
|
||||
|
||||
class Card
|
||||
{
|
||||
private int $id;
|
||||
public Column $column;
|
||||
public string $value;
|
||||
private bool $is_done;
|
||||
private static PDO $pdo;
|
||||
private function __construct(int $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
public static function initPDO(){
|
||||
self::$pdo = new PDO("mysql:host=" . Config::$database_host . ";dbname=" . Config::$database_name, Config::$database_user, Config::$database_password);
|
||||
}
|
||||
public static function getCards(array $columns) : array{
|
||||
$cards = array();
|
||||
$sql = "SELECT * FROM `cards` WHERE 1";
|
||||
foreach (self::$pdo->query($sql) as $row) {
|
||||
$card = new Card($row["id"]);
|
||||
$card->value = $row["value"];
|
||||
$card->is_done = $row["is_done"];
|
||||
$column_id = $row["column_id"];
|
||||
|
||||
if($column_id == null&& $column_id !== 0){
|
||||
$card->column = $columns[$card->is_done ? "done" : "unsorted"];
|
||||
$columns[$card->is_done ? "done" : "unsorted"]->cards[$card->id] = $card;
|
||||
$cards[] = $card;
|
||||
continue;
|
||||
}
|
||||
|
||||
$card->column = $columns[$column_id];
|
||||
$columns[$column_id]->cards[$card->id] = $card;
|
||||
$cards[] = $card;
|
||||
}
|
||||
return $cards;
|
||||
}
|
||||
public static function createCard(string $value, int $column_id) : Card{
|
||||
$lines = explode("\\r\\n", $value);
|
||||
$value = "";
|
||||
foreach ($lines as $line){
|
||||
$value .= $line . PHP_EOL;
|
||||
}
|
||||
if($column_id < 0){
|
||||
$sql = self::$pdo->prepare("INSERT INTO `cards`(`value`) VALUES (:value)");
|
||||
$sql->bindParam(':value', $value);
|
||||
}else{
|
||||
$sql = self::$pdo->prepare("INSERT INTO `cards`(`value`, `column_id`) VALUES (:value, :column_id)");
|
||||
$sql->bindParam(':value', $value);
|
||||
$sql->bindParam(':column_id', $column_id);
|
||||
}
|
||||
|
||||
$sql->execute();
|
||||
$new_id = self::$pdo->lastInsertId();
|
||||
$card = new Card($new_id);
|
||||
$card->value = $value;
|
||||
$fake_column = new Column($column_id);
|
||||
$card->column = $fake_column;
|
||||
return $card;
|
||||
}
|
||||
public static function deleteCard(int $id): bool{
|
||||
$sql = self::$pdo->prepare("DELETE FROM `cards` WHERE `id`=:id");
|
||||
$sql->bindParam(':id', $id);
|
||||
return $sql->execute();
|
||||
}
|
||||
public static function moveCard(int $card_id, int $column_id): bool{
|
||||
$sql = self::$pdo->prepare("UPDATE `cards` SET `column_id` = :column_id WHERE `id`=:id");
|
||||
$new_column_id = $column_id >= 0 ? $column_id : null;
|
||||
$sql->bindParam(':column_id', $new_column_id);
|
||||
$sql->bindParam(':id', $card_id);
|
||||
return $sql->execute();
|
||||
}
|
||||
public static function setCardValue(int $card_id, string $value): bool{
|
||||
$sql = self::$pdo->prepare("UPDATE `cards` SET `value` = '$value' WHERE `id`=:id");
|
||||
$sql->bindParam(':id', $card_id);
|
||||
return $sql->execute();
|
||||
}
|
||||
public static function setCardDone(int $card_id, bool $is_done): bool{
|
||||
$sql = self::$pdo->prepare("UPDATE `cards` SET `is_done` = :is_done WHERE `id`=:id");
|
||||
$sql->bindParam(':is_done', $is_done);
|
||||
$sql->bindParam(':id', $card_id);
|
||||
return $sql->execute();
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
51
.checkout/src/Model/Column.php
Normal file
51
.checkout/src/Model/Column.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
use Config;
|
||||
use PDO;
|
||||
|
||||
|
||||
class Column
|
||||
{
|
||||
private int $id;
|
||||
public array $cards;
|
||||
public string $title;
|
||||
private static PDO $pdo;
|
||||
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
public static function initPDO(){
|
||||
self::$pdo = new PDO("mysql:host=" . Config::$database_host . ";dbname=" . Config::$database_name, Config::$database_user, Config::$database_password);
|
||||
}
|
||||
public static function getColumns() : array{
|
||||
$columns = array();
|
||||
$unsorted_column = new Column(-1);
|
||||
$unsorted_column->title = "Unsorted";
|
||||
$unsorted_column->cards = array();
|
||||
$columns["unsorted"] = $unsorted_column;
|
||||
$sql = "SELECT * FROM `columns` WHERE 1";
|
||||
foreach (self::$pdo->query($sql) as $row) {
|
||||
$column_id = "" . $row["id"];
|
||||
$column = new Column($row["id"]);
|
||||
$column->title = $row["title"];
|
||||
$column->cards = array();
|
||||
$columns[$column_id] = $column;
|
||||
}
|
||||
$done_column = new Column(-2);
|
||||
$done_column->title = "Done";
|
||||
$done_column->cards = array();
|
||||
$columns["done"] = $done_column;
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
public function getCards(): array{
|
||||
return $this->cards;
|
||||
}
|
||||
}
|
90
.checkout/symfony.lock
Normal file
90
.checkout/symfony.lock
Normal file
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"symfony/console": {
|
||||
"version": "6.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.3",
|
||||
"ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
|
||||
},
|
||||
"files": [
|
||||
"./bin/console"
|
||||
]
|
||||
},
|
||||
"symfony/flex": {
|
||||
"version": "2.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
|
||||
},
|
||||
"files": [
|
||||
"./.env"
|
||||
]
|
||||
},
|
||||
"symfony/framework-bundle": {
|
||||
"version": "6.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.2",
|
||||
"ref": "af47254c5e4cd543e6af3e4508298ffebbdaddd3"
|
||||
},
|
||||
"files": [
|
||||
"./config/packages/cache.yaml",
|
||||
"./config/packages/framework.yaml",
|
||||
"./config/preload.php",
|
||||
"./config/routes/framework.yaml",
|
||||
"./config/services.yaml",
|
||||
"./public/index.php",
|
||||
"./src/Controller/.gitignore",
|
||||
"./src/Kernel.php"
|
||||
]
|
||||
},
|
||||
"symfony/routing": {
|
||||
"version": "6.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.2",
|
||||
"ref": "e0a11b4ccb8c9e70b574ff5ad3dfdcd41dec5aa6"
|
||||
},
|
||||
"files": [
|
||||
"./config/packages/routing.yaml",
|
||||
"./config/routes.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/twig-bundle": {
|
||||
"version": "6.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.4",
|
||||
"ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387"
|
||||
},
|
||||
"files": [
|
||||
"./config/packages/twig.yaml",
|
||||
"./templates/base.html.twig"
|
||||
]
|
||||
},
|
||||
"symfony/webpack-encore-bundle": {
|
||||
"version": "1.16",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.10",
|
||||
"ref": "f8fc53f1942f76679e9ee3c25fd44865355707b5"
|
||||
},
|
||||
"files": [
|
||||
"./assets/app.js",
|
||||
"./assets/bootstrap.ts",
|
||||
"./assets/controllers.json",
|
||||
"./assets/controllers/hello_controller.js",
|
||||
"./assets/styles/app.css",
|
||||
"./config/packages/webpack_encore.yaml",
|
||||
"./package.json",
|
||||
"./webpack.config.js"
|
||||
]
|
||||
}
|
||||
}
|
19
.checkout/templates/base.html.twig
Normal file
19
.checkout/templates/base.html.twig
Normal file
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}Welcome!{% endblock %}</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
|
||||
{# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #}
|
||||
{% block stylesheets %}
|
||||
{{ encore_entry_link_tags('app') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{{ encore_entry_script_tags('app') }}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% block body %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
20
.checkout/templates/kanban/board.html.twig
Normal file
20
.checkout/templates/kanban/board.html.twig
Normal file
|
@ -0,0 +1,20 @@
|
|||
<!doctype html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css">
|
||||
|
||||
{% block stylesheets %}
|
||||
{{ encore_entry_link_tags('app') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{{ encore_entry_script_tags('app') }}
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
{% for column in columns %}
|
||||
{{ include('kanban/column.html.twig') }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</body>
|
8
.checkout/templates/kanban/card.html.twig
Normal file
8
.checkout/templates/kanban/card.html.twig
Normal file
|
@ -0,0 +1,8 @@
|
|||
<li id="card{{ card.getId }}" db_id="{{ card.getId }}" class="card" {{ stimulus_controller('card') }}>
|
||||
<button class="card-button card-edit-button fa-solid fa-rotate-left" {{ stimulus_action('card', 'edit_card_revert') }} {{ stimulus_target('card', 'revert') }} style="display: none"></button>
|
||||
<button class="card-button card-edit-button fa-solid fa-floppy-disk" {{ stimulus_action('card', 'edit_card_save') }} {{ stimulus_target('card', 'save') }} style="display: none"></button>
|
||||
<button class="card-button fa-solid fa-trash" {{ stimulus_action('card', 'delete_card') }} {{ stimulus_target('card', 'delete') }}></button>
|
||||
<button class="card-button fa-solid fa-pen" {{ stimulus_action('card', 'edit_card') }} {{ stimulus_target('card', 'edit') }}></button>
|
||||
<p {{ stimulus_target('card', 'value') }}>{{ card.value | nl2br }}</p>
|
||||
<textarea class="card-edit-textarea" {{ stimulus_target('card', 'textarea') }} style="display: none"></textarea>
|
||||
</li>
|
20
.checkout/templates/kanban/column.html.twig
Normal file
20
.checkout/templates/kanban/column.html.twig
Normal file
|
@ -0,0 +1,20 @@
|
|||
<div class='column' id='{{ column.getId}}' {{ stimulus_controller('column') }}>
|
||||
<div class="column-title-bar">
|
||||
<h2>{{ column.title }}</h2>
|
||||
{% if column.getId != -2 %}
|
||||
<button class="add-card-button fa-solid fa-plus fa-xl" {{ stimulus_action('column', 'create_card') }}></button>
|
||||
{%endif %}
|
||||
</div>
|
||||
{% if column.getId != -2 %}
|
||||
<div class="add-card-textarea-wrapper">
|
||||
<textarea class="add-card-textarea" {{ stimulus_target('column', 'value') }}></textarea>
|
||||
</div>
|
||||
{%endif %}
|
||||
<div class="card-list-wrapper">
|
||||
<ul class='card-list' {{ stimulus_target('column', 'output') }}>
|
||||
{% for card in column.getCards %}
|
||||
{{ include('kanban/card.html.twig') }}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
1
.checkout/tsconfig.json
Normal file
1
.checkout/tsconfig.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
77
.checkout/webpack.config.js
Normal file
77
.checkout/webpack.config.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
const Encore = require('@symfony/webpack-encore');
|
||||
|
||||
// Manually configure the runtime environment if not already configured yet by the "encore" command.
|
||||
// It's useful when you use tools that rely on webpack.config.js file.
|
||||
if (!Encore.isRuntimeEnvironmentConfigured()) {
|
||||
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
|
||||
}
|
||||
|
||||
Encore
|
||||
// directory where compiled assets will be stored
|
||||
.setOutputPath('public/build/')
|
||||
// public path used by the web server to access the output path
|
||||
.setPublicPath('/build')
|
||||
// only needed for CDN's or subdirectory deploy
|
||||
//.setManifestKeyPrefix('build/')
|
||||
|
||||
/*
|
||||
* ENTRY CONFIG
|
||||
*
|
||||
* Each entry will result in one JavaScript file (e.g. app.js)
|
||||
* and one CSS file (e.g. app.css) if your JavaScript imports CSS.
|
||||
*/
|
||||
.addEntry('app', './assets/app.ts')
|
||||
|
||||
// enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js)
|
||||
.enableStimulusBridge('./assets/controllers.json')
|
||||
|
||||
// When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
|
||||
.splitEntryChunks()
|
||||
|
||||
// will require an extra script tag for runtime.js
|
||||
// but, you probably want this, unless you're building a single-page app
|
||||
.enableSingleRuntimeChunk()
|
||||
|
||||
/*
|
||||
* FEATURE CONFIG
|
||||
*
|
||||
* Enable & configure other features below. For a full
|
||||
* list of features, see:
|
||||
* https://symfony.com/doc/current/frontend.html#adding-more-features
|
||||
*/
|
||||
.cleanupOutputBeforeBuild()
|
||||
.enableBuildNotifications()
|
||||
.enableSourceMaps(!Encore.isProduction())
|
||||
// enables hashed filenames (e.g. app.abc123.css)
|
||||
.enableVersioning(Encore.isProduction())
|
||||
|
||||
// configure Babel
|
||||
// .configureBabel((config) => {
|
||||
// config.plugins.push('@babel/a-babel-plugin');
|
||||
// })
|
||||
|
||||
// enables and configure @babel/preset-env polyfills
|
||||
.configureBabelPresetEnv((config) => {
|
||||
config.useBuiltIns = 'usage';
|
||||
config.corejs = '3.23';
|
||||
})
|
||||
|
||||
// enables Sass/SCSS support
|
||||
.enableSassLoader()
|
||||
|
||||
// uncomment if you use TypeScript
|
||||
.enableTypeScriptLoader()
|
||||
|
||||
// uncomment if you use React
|
||||
//.enableReactPreset()
|
||||
|
||||
// uncomment to get integrity="..." attributes on your script & link tags
|
||||
// requires WebpackEncoreBundle 1.4 or higher
|
||||
//.enableIntegrityHashes(Encore.isProduction())
|
||||
|
||||
// uncomment if you're having problems with a jQuery plugin
|
||||
//.autoProvidejQuery()
|
||||
.enableForkedTypeScriptTypesChecking()
|
||||
;
|
||||
|
||||
module.exports = Encore.getWebpackConfig();
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
Loading…
Reference in a new issue