Compare commits
46 commits
alpha-depl
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4dd445be57 | |||
| 4c31dbbed0 | |||
| b756df38a9 | |||
| 297138b0d4 | |||
| 12ea9ea1fb | |||
| 8b4ffb83ec | |||
| 0964187f22 | |||
| 83dd857776 | |||
| 650bec3f57 | |||
| e1dfb14d4d | |||
| 2082b20d5a | |||
| 2de996a194 | |||
| 976936d480 | |||
| bf0548ecfe | |||
| 4abae91a5a | |||
| 89ef15f41d | |||
| 2a8e2835f3 | |||
| bf2001d39c | |||
| 3f76aeeb3c | |||
| 02e13871bb | |||
| fd11eaff33 | |||
| c36230b8ba | |||
| 110d75f2b7 | |||
| 70500c49a1 | |||
| 7b0f05a448 | |||
| 889ad3275b | |||
| bf03407bb9 | |||
| e576aa1e39 | |||
| acc5357627 | |||
| b400ba7cea | |||
| 92c7fd43b1 | |||
| 096e541969 | |||
| 1082011941 | |||
| fa1d5b8bce | |||
| 0a48759576 | |||
| 13755bacdb | |||
| aa1552db81 | |||
| 7f1c634996 | |||
| 65568ac27b | |||
| c258754069 | |||
| 3e2cef9907 | |||
| fab4981508 | |||
| 934deddec4 | |||
| 84fc1d2d93 | |||
| 2f1566718e | |||
| 2293751fe2 |
149 changed files with 2770 additions and 2113 deletions
|
|
@ -41,3 +41,5 @@
|
||||||
|
|
||||||
/.forgejo/
|
/.forgejo/
|
||||||
/core*
|
/core*
|
||||||
|
|
||||||
|
/.devenv
|
||||||
|
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -74,3 +74,5 @@ public/504.html
|
||||||
public/505.html
|
public/505.html
|
||||||
public/507.html
|
public/507.html
|
||||||
public/510.html
|
public/510.html
|
||||||
|
|
||||||
|
/.devenv
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
ruby-3.3.5
|
ruby-3.4
|
||||||
|
|
|
||||||
188
Dockerfile
188
Dockerfile
|
|
@ -1,19 +1,19 @@
|
||||||
|
ARG RUBY_VERSION=3.4
|
||||||
|
|
||||||
ARG NAME=app
|
ARG NAME=app
|
||||||
ARG UID=1000
|
ARG UID=1000
|
||||||
ARG GID=1000
|
ARG GID=1000
|
||||||
ARG APP_PORT=3000
|
ARG INSTALL_DIR=/home/${NAME}/src
|
||||||
ARG INSTALL_DIR=/${NAME}
|
|
||||||
ARG RUBY_VERSION=3.2.5
|
FROM ruby:${RUBY_VERSION} as development
|
||||||
FROM ruby:${RUBY_VERSION} AS development
|
|
||||||
|
LABEL maintainer='david@hohl.cloud'
|
||||||
|
|
||||||
ARG NAME
|
ARG NAME
|
||||||
ARG UID
|
ARG UID
|
||||||
ARG GID
|
ARG GID
|
||||||
ARG APP_PORT
|
|
||||||
ARG INSTALL_DIR
|
ARG INSTALL_DIR
|
||||||
|
|
||||||
LABEL maintainer='david@hohl.cloud'
|
|
||||||
|
|
||||||
WORKDIR ${INSTALL_DIR}
|
WORKDIR ${INSTALL_DIR}
|
||||||
|
|
||||||
ENV GEM_HOME=${INSTALL_DIR}/.bundle
|
ENV GEM_HOME=${INSTALL_DIR}/.bundle
|
||||||
|
|
@ -39,6 +39,7 @@ RUN \
|
||||||
--disabled-login \
|
--disabled-login \
|
||||||
--shell /bin/bash \
|
--shell /bin/bash \
|
||||||
${NAME} && \
|
${NAME} && \
|
||||||
|
chown -R ${NAME}:${NAME} /home/${NAME} && \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install -yqq --no-install-recommends \
|
apt-get install -yqq --no-install-recommends \
|
||||||
gnupg2 \
|
gnupg2 \
|
||||||
|
|
@ -47,9 +48,8 @@ RUN \
|
||||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
|
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
|
||||||
apt-get update -yqq && \
|
apt-get update -yqq && \
|
||||||
apt-get install -yqq --no-install-recommends \
|
apt-get install -yqq --no-install-recommends \
|
||||||
sqlite3 nodejs npm sassc yarn libvips fish ranger pandoc libjemalloc2 && \
|
sqlite3 nodejs npm sassc yarn libvips libjemalloc2 && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
npm install tabby-agent && \
|
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
|
||||||
truncate -s 0 /var/log/*log && \
|
truncate -s 0 /var/log/*log && \
|
||||||
gem update --system && \
|
gem update --system && \
|
||||||
|
|
@ -57,135 +57,91 @@ RUN \
|
||||||
|
|
||||||
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
||||||
|
|
||||||
USER ${NAME}
|
COPY bin/dev_entrypoint /usr/local/bin/dev_entrypoint
|
||||||
|
|
||||||
RUN mkdir -p ~/.config/fish && echo "set fish_greeting" >> ~/.config/fish/config.fish
|
|
||||||
RUN \
|
|
||||||
echo >> ~/.config/fish/config.fish &&\
|
|
||||||
echo "function fish_prompt" >> ~/.config/fish/config.fish &&\
|
|
||||||
echo " set -l last_status \$status" >> ~/.config/fish/config.fish &&\
|
|
||||||
echo " set -l stat" >> ~/.config/fish/config.fish &&\
|
|
||||||
echo " if test \$last_status -ne 0" >> ~/.config/fish/config.fish &&\
|
|
||||||
echo " set stat (set_color red)\"[\$last_status]\"(set_color normal)" >> ~/.config/fish/config.fish &&\
|
|
||||||
echo " end" >> ~/.config/fish/config.fish &&\
|
|
||||||
echo " string join '' -- (set_color green) (prompt_pwd) (set_color normal) \$stat ' 🐳 '" >> ~/.config/fish/config.fish && \
|
|
||||||
echo "end" >> ~/.config/fish/config.fish
|
|
||||||
|
|
||||||
FROM ruby:${RUBY_VERSION}-alpine AS builder
|
|
||||||
|
|
||||||
ARG NAME
|
|
||||||
ARG UID
|
|
||||||
ARG GID
|
|
||||||
ARG APP_PORT
|
|
||||||
ARG INSTALL_DIR
|
|
||||||
|
|
||||||
WORKDIR ${INSTALL_DIR}
|
|
||||||
|
|
||||||
ENV GEM_HOME=${INSTALL_DIR}/.bundle
|
|
||||||
|
|
||||||
ENV \
|
|
||||||
LANG=C.UTF-8 \
|
|
||||||
INSTALL_DIR=${INSTALL_DIR} \
|
|
||||||
RAILS_ENV=development \
|
|
||||||
TZ=Europe/Zurich \
|
|
||||||
PATH=${INSTALL_DIR}/bin:$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH \
|
|
||||||
EDITOR=vim
|
|
||||||
|
|
||||||
RUN apk add --update --no-cache \
|
|
||||||
binutils-gold \
|
|
||||||
build-base \
|
|
||||||
curl \
|
|
||||||
file \
|
|
||||||
g++ \
|
|
||||||
gcc \
|
|
||||||
git \
|
|
||||||
less \
|
|
||||||
libstdc++ \
|
|
||||||
libffi-dev \
|
|
||||||
libc-dev \
|
|
||||||
linux-headers \
|
|
||||||
libxml2-dev \
|
|
||||||
libxslt-dev \
|
|
||||||
libgcrypt-dev \
|
|
||||||
make \
|
|
||||||
netcat-openbsd \
|
|
||||||
nodejs \
|
|
||||||
openssl \
|
|
||||||
pkgconfig \
|
|
||||||
tzdata \
|
|
||||||
yarn \
|
|
||||||
sqlite \
|
|
||||||
vips-dev \
|
|
||||||
npm \
|
|
||||||
sassc \
|
|
||||||
jemalloc \
|
|
||||||
pandoc-cli \
|
|
||||||
sqlite-libs \
|
|
||||||
build-base && \
|
|
||||||
truncate -s 0 /var/log/*log && \
|
|
||||||
gem update --system && \
|
|
||||||
bundle config set app_config ${GEM_HOME}
|
|
||||||
|
|
||||||
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
|
||||||
|
|
||||||
USER ${NAME}
|
USER ${NAME}
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/dev_entrypoint"]
|
||||||
|
|
||||||
|
CMD ["/bin/sh", "-c", "dev"]
|
||||||
|
|
||||||
|
FROM development AS build
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
COPY Gemfile Gemfile.lock package.json yarn.lock ./
|
# Wir wollen die bundles nicht im app directory
|
||||||
|
ENV GEM_HOME=/usr/local/bundle \
|
||||||
|
BUNDLE_WITHOUT="development test" \
|
||||||
|
RAILS_ENV=production \
|
||||||
|
SECRET_KEY_BASE_DUMMY=1
|
||||||
|
|
||||||
|
ENV PATH=${INSTALL_DIR}/bin:$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH
|
||||||
|
|
||||||
RUN bundle config without test development && bundle install && yarn install
|
COPY ./Gemfile ./Gemfile.lock ./
|
||||||
|
|
||||||
FROM builder AS assets
|
|
||||||
|
|
||||||
|
RUN bundle config set app_config ${GEM_HOME} && \
|
||||||
|
bundle config && \
|
||||||
|
bundle install && \
|
||||||
|
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
|
||||||
|
bundle exec bootsnap precompile --gemfile
|
||||||
|
|
||||||
|
RUN bundle config
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
COPY --from=builder ${INSTALL_DIR}/.bundle ${INSTALL_DIR}/.bundle
|
RUN bundle exec bootsnap precompile app/ lib/ && \
|
||||||
COPY --from=builder ${INSTALL_DIR}/node_modules ${INSTALL_DIR}/node_modules
|
rails assets:precompile && \
|
||||||
|
rm -rf log/* tmp/* && \
|
||||||
|
chown -R ${NAME}:${NAME} log tmp
|
||||||
|
|
||||||
RUN RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 rails assets:precompile
|
|
||||||
|
|
||||||
FROM ruby:${RUBY_VERSION}-alpine AS production
|
FROM ruby:${RUBY_VERSION}-slim AS release
|
||||||
|
|
||||||
ARG INSTALL_DIR
|
ARG UID
|
||||||
ARG NAME
|
ARG GID
|
||||||
|
ARG NAME=app
|
||||||
|
ARG INSTALL_DIR
|
||||||
|
ARG BUILD_DIR=${INSTALL_DIR}
|
||||||
|
ARG INSTALL_DIR=/app
|
||||||
|
|
||||||
|
ENV GEM_HOME=/usr/local/bundle \
|
||||||
|
BUNDLE_WITHOUT="development test" \
|
||||||
|
BUNDLE_SYSTEM=1 \
|
||||||
|
RAILS_ENV=production \
|
||||||
|
LANG=C.UTF-8 \
|
||||||
|
INSTALL_DIR=${INSTALL_DIR} \
|
||||||
|
TZ=Europe/Zurich
|
||||||
|
|
||||||
|
ENV PATH=${INSTALL_DIR}/bin:$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH
|
||||||
|
|
||||||
WORKDIR ${INSTALL_DIR}
|
WORKDIR ${INSTALL_DIR}
|
||||||
|
|
||||||
ENV GEM_HOME=${INSTALL_DIR}/.bundle
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
|
||||||
|
echo $TZ > /etc/timezone && \
|
||||||
|
adduser --disabled-password --disabled-login ${NAME} &&\
|
||||||
|
apt-get update -yqq && \
|
||||||
|
apt-get install -yqq --no-install-recommends \
|
||||||
|
sqlite3 libjemalloc2 && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
|
||||||
|
gem update --system && \
|
||||||
|
truncate -s 0 /var/log/*log
|
||||||
|
|
||||||
|
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
|
||||||
|
|
||||||
ENV \
|
RUN pwd
|
||||||
RAILS_ENV=production \
|
|
||||||
PATH=${INSTALL_DIR}/bin:$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH \
|
|
||||||
TZ=Europe/Zurich
|
|
||||||
|
|
||||||
RUN \
|
COPY --from=build ${GEM_HOME} ${GEM_HOME}
|
||||||
adduser ${NAME} --disabled-password --shell /bin/ash && \
|
COPY --from=build ${BUILD_DIR} .
|
||||||
apk add --update --no-cache \
|
|
||||||
tzdata \
|
RUN ls -la && chown -R ${NAME}:${NAME} ./tmp ./log ./storage
|
||||||
sqlite \
|
|
||||||
vips-dev \
|
|
||||||
jemalloc && \
|
|
||||||
gem update --system && \
|
|
||||||
bundle config set app_config ${GEM_HOME} && \
|
|
||||||
bundle config set without development test && \
|
|
||||||
apk add patchelf && \
|
|
||||||
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby && \
|
|
||||||
apk del patchelf && \
|
|
||||||
truncate -s 0 /var/log/*log
|
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
COPY . .
|
ENTRYPOINT ["bin/docker-entrypoint"]
|
||||||
|
|
||||||
COPY --from=builder ${INSTALL_DIR}/.bundle ${INSTALL_DIR}/.bundle
|
|
||||||
COPY --from=assets ${INSTALL_DIR}/public/assets ${INSTALL_DIR}/public/assets
|
|
||||||
|
|
||||||
RUN chown -R ${NAME}:${NAME} ${INSTALL_DIR}/tmp ${INSTALL_DIR}/log ${INSTALL_DIR}/storage && \
|
|
||||||
date +"%Y-%m-%d %H:%M:%S %Z" >> .build_version
|
|
||||||
|
|
||||||
USER ${NAME}
|
USER ${NAME}
|
||||||
|
|
||||||
ENTRYPOINT [ "bin/entrypoint" ]
|
CMD ["./bin/rails", "server", "-b", "0"]
|
||||||
|
|
||||||
|
|
||||||
CMD [ "rails", "server", "--binding", "0.0.0.0", "--no-daemon", "--port" , "3000" ]
|
|
||||||
|
|
|
||||||
4
Gemfile
4
Gemfile
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
ruby "3.2.5"
|
|
||||||
|
|
||||||
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
|
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
|
||||||
gem "rails", "~> 8.0"
|
gem "rails", "~> 8.0"
|
||||||
|
|
||||||
|
|
@ -50,6 +48,7 @@ gem "bootsnap", require: false
|
||||||
gem "bootstrap_form"
|
gem "bootstrap_form"
|
||||||
gem "caxlsx"
|
gem "caxlsx"
|
||||||
gem "caxlsx_rails"
|
gem "caxlsx_rails"
|
||||||
|
gem "deepl-rb", require: "deepl"
|
||||||
gem "image_processing", "~> 1.2"
|
gem "image_processing", "~> 1.2"
|
||||||
gem "openxml-docx"
|
gem "openxml-docx"
|
||||||
gem "pagy", "~> 9.0"
|
gem "pagy", "~> 9.0"
|
||||||
|
|
@ -58,6 +57,7 @@ gem "prawn-markup"
|
||||||
gem "prawn-rails"
|
gem "prawn-rails"
|
||||||
gem "sablon"
|
gem "sablon"
|
||||||
gem "slim"
|
gem "slim"
|
||||||
|
gem "solid_queue"
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
|
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
|
||||||
|
|
|
||||||
395
Gemfile.lock
395
Gemfile.lock
|
|
@ -1,29 +1,29 @@
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (8.0.0)
|
actioncable (8.0.2)
|
||||||
actionpack (= 8.0.0)
|
actionpack (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
actionmailbox (8.0.0)
|
actionmailbox (8.0.2)
|
||||||
actionpack (= 8.0.0)
|
actionpack (= 8.0.2)
|
||||||
activejob (= 8.0.0)
|
activejob (= 8.0.2)
|
||||||
activerecord (= 8.0.0)
|
activerecord (= 8.0.2)
|
||||||
activestorage (= 8.0.0)
|
activestorage (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
mail (>= 2.8.0)
|
mail (>= 2.8.0)
|
||||||
actionmailer (8.0.0)
|
actionmailer (8.0.2)
|
||||||
actionpack (= 8.0.0)
|
actionpack (= 8.0.2)
|
||||||
actionview (= 8.0.0)
|
actionview (= 8.0.2)
|
||||||
activejob (= 8.0.0)
|
activejob (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
mail (>= 2.8.0)
|
mail (>= 2.8.0)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
actionpack (8.0.0)
|
actionpack (8.0.2)
|
||||||
actionview (= 8.0.0)
|
actionview (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
rack (>= 2.2.4)
|
rack (>= 2.2.4)
|
||||||
rack-session (>= 1.0.1)
|
rack-session (>= 1.0.1)
|
||||||
|
|
@ -31,35 +31,35 @@ GEM
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
useragent (~> 0.16)
|
useragent (~> 0.16)
|
||||||
actiontext (8.0.0)
|
actiontext (8.0.2)
|
||||||
actionpack (= 8.0.0)
|
actionpack (= 8.0.2)
|
||||||
activerecord (= 8.0.0)
|
activerecord (= 8.0.2)
|
||||||
activestorage (= 8.0.0)
|
activestorage (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (8.0.0)
|
actionview (8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.11)
|
erubi (~> 1.11)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
activejob (8.0.0)
|
activejob (8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (8.0.0)
|
activemodel (8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
activerecord (8.0.0)
|
activerecord (8.0.2)
|
||||||
activemodel (= 8.0.0)
|
activemodel (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
timeout (>= 0.4.0)
|
timeout (>= 0.4.0)
|
||||||
activestorage (8.0.0)
|
activestorage (8.0.2)
|
||||||
actionpack (= 8.0.0)
|
actionpack (= 8.0.2)
|
||||||
activejob (= 8.0.0)
|
activejob (= 8.0.2)
|
||||||
activerecord (= 8.0.0)
|
activerecord (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
activesupport (8.0.0)
|
activesupport (8.0.2)
|
||||||
base64
|
base64
|
||||||
benchmark (>= 0.3)
|
benchmark (>= 0.3)
|
||||||
bigdecimal
|
bigdecimal
|
||||||
|
|
@ -74,18 +74,18 @@ GEM
|
||||||
uri (>= 0.13.1)
|
uri (>= 0.13.1)
|
||||||
addressable (2.8.7)
|
addressable (2.8.7)
|
||||||
public_suffix (>= 2.0.2, < 7.0)
|
public_suffix (>= 2.0.2, < 7.0)
|
||||||
ast (2.4.2)
|
ast (2.4.3)
|
||||||
base64 (0.2.0)
|
base64 (0.2.0)
|
||||||
bcrypt (3.1.20)
|
bcrypt (3.1.20)
|
||||||
benchmark (0.4.0)
|
benchmark (0.4.0)
|
||||||
bigdecimal (3.1.8)
|
bigdecimal (3.1.9)
|
||||||
bindex (0.8.1)
|
bindex (0.8.1)
|
||||||
bootsnap (1.18.3)
|
bootsnap (1.18.6)
|
||||||
msgpack (~> 1.2)
|
msgpack (~> 1.2)
|
||||||
bootstrap_form (5.4.0)
|
bootstrap_form (5.4.0)
|
||||||
actionpack (>= 6.1)
|
actionpack (>= 6.1)
|
||||||
activemodel (>= 6.1)
|
activemodel (>= 6.1)
|
||||||
brakeman (6.1.2)
|
brakeman (7.0.2)
|
||||||
racc
|
racc
|
||||||
builder (3.3.0)
|
builder (3.3.0)
|
||||||
capybara (3.40.0)
|
capybara (3.40.0)
|
||||||
|
|
@ -97,7 +97,7 @@ GEM
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
regexp_parser (>= 1.5, < 3.0)
|
regexp_parser (>= 1.5, < 3.0)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
caxlsx (4.1.0)
|
caxlsx (4.2.0)
|
||||||
htmlentities (~> 4.3, >= 4.3.4)
|
htmlentities (~> 4.3, >= 4.3.4)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
nokogiri (~> 1.10, >= 1.10.4)
|
nokogiri (~> 1.10, >= 1.10.4)
|
||||||
|
|
@ -105,47 +105,57 @@ GEM
|
||||||
caxlsx_rails (0.6.4)
|
caxlsx_rails (0.6.4)
|
||||||
actionpack (>= 3.1)
|
actionpack (>= 3.1)
|
||||||
caxlsx (>= 3.0)
|
caxlsx (>= 3.0)
|
||||||
concurrent-ruby (1.3.3)
|
concurrent-ruby (1.3.5)
|
||||||
connection_pool (2.4.1)
|
connection_pool (2.5.3)
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
cssbundling-rails (1.4.0)
|
cssbundling-rails (1.4.3)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
date (3.4.0)
|
date (3.4.1)
|
||||||
debug (1.9.2)
|
debug (1.10.0)
|
||||||
irb (~> 1.10)
|
irb (~> 1.10)
|
||||||
reline (>= 0.3.8)
|
reline (>= 0.3.8)
|
||||||
|
deepl-rb (3.2.0)
|
||||||
drb (2.2.1)
|
drb (2.2.1)
|
||||||
erubi (1.13.0)
|
erubi (1.13.1)
|
||||||
ffi (1.17.0-aarch64-linux-gnu)
|
et-orbi (1.2.11)
|
||||||
ffi (1.17.0-arm-linux-gnu)
|
tzinfo
|
||||||
ffi (1.17.0-arm64-darwin)
|
ffi (1.17.2-aarch64-linux-gnu)
|
||||||
ffi (1.17.0-x86-linux-gnu)
|
ffi (1.17.2-aarch64-linux-musl)
|
||||||
ffi (1.17.0-x86_64-darwin)
|
ffi (1.17.2-arm-linux-gnu)
|
||||||
ffi (1.17.0-x86_64-linux-gnu)
|
ffi (1.17.2-arm-linux-musl)
|
||||||
|
ffi (1.17.2-arm64-darwin)
|
||||||
|
ffi (1.17.2-x86_64-darwin)
|
||||||
|
ffi (1.17.2-x86_64-linux-gnu)
|
||||||
|
ffi (1.17.2-x86_64-linux-musl)
|
||||||
|
fugit (1.11.1)
|
||||||
|
et-orbi (~> 1, >= 1.2.11)
|
||||||
|
raabro (~> 1.4)
|
||||||
globalid (1.2.1)
|
globalid (1.2.1)
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 6.1)
|
||||||
hpricot (0.8.6)
|
hpricot (0.8.6)
|
||||||
html2slim (0.2.0)
|
html2slim (0.2.0)
|
||||||
hpricot
|
hpricot
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
i18n (1.14.5)
|
i18n (1.14.7)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
image_processing (1.12.2)
|
image_processing (1.14.0)
|
||||||
mini_magick (>= 4.9.5, < 5)
|
mini_magick (>= 4.9.5, < 6)
|
||||||
ruby-vips (>= 2.0.17, < 3)
|
ruby-vips (>= 2.0.17, < 3)
|
||||||
io-console (0.7.2)
|
io-console (0.8.0)
|
||||||
irb (1.14.0)
|
irb (1.15.2)
|
||||||
|
pp (>= 0.6.0)
|
||||||
rdoc (>= 4.0.0)
|
rdoc (>= 4.0.0)
|
||||||
reline (>= 0.4.2)
|
reline (>= 0.4.2)
|
||||||
jbuilder (2.12.0)
|
jbuilder (2.13.0)
|
||||||
actionview (>= 5.0.0)
|
actionview (>= 5.0.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
jsbundling-rails (1.3.0)
|
jsbundling-rails (1.3.1)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
json (2.7.2)
|
json (2.12.0)
|
||||||
language_server-protocol (3.17.0.3)
|
language_server-protocol (3.17.0.5)
|
||||||
logger (1.6.1)
|
lint_roller (1.1.0)
|
||||||
loofah (2.22.0)
|
logger (1.7.0)
|
||||||
|
loofah (2.24.1)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.12.0)
|
nokogiri (>= 1.12.0)
|
||||||
mail (2.8.1)
|
mail (2.8.1)
|
||||||
|
|
@ -155,31 +165,37 @@ GEM
|
||||||
net-smtp
|
net-smtp
|
||||||
marcel (1.0.4)
|
marcel (1.0.4)
|
||||||
matrix (0.4.2)
|
matrix (0.4.2)
|
||||||
mini_magick (4.13.2)
|
mini_magick (5.2.0)
|
||||||
|
benchmark
|
||||||
|
logger
|
||||||
mini_mime (1.1.5)
|
mini_mime (1.1.5)
|
||||||
minitest (5.24.1)
|
minitest (5.25.5)
|
||||||
msgpack (1.7.2)
|
msgpack (1.8.0)
|
||||||
net-imap (0.5.0)
|
net-imap (0.5.8)
|
||||||
date
|
date
|
||||||
net-protocol
|
net-protocol
|
||||||
net-pop (0.1.2)
|
net-pop (0.1.2)
|
||||||
net-protocol
|
net-protocol
|
||||||
net-protocol (0.2.2)
|
net-protocol (0.2.2)
|
||||||
timeout
|
timeout
|
||||||
net-smtp (0.5.0)
|
net-smtp (0.5.1)
|
||||||
net-protocol
|
net-protocol
|
||||||
nio4r (2.7.3)
|
nio4r (2.7.4)
|
||||||
nokogiri (1.16.6-aarch64-linux)
|
nokogiri (1.18.8-aarch64-linux-gnu)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.16.6-arm-linux)
|
nokogiri (1.18.8-aarch64-linux-musl)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.16.6-arm64-darwin)
|
nokogiri (1.18.8-arm-linux-gnu)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.16.6-x86-linux)
|
nokogiri (1.18.8-arm-linux-musl)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.16.6-x86_64-darwin)
|
nokogiri (1.18.8-arm64-darwin)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.16.6-x86_64-linux)
|
nokogiri (1.18.8-x86_64-darwin)
|
||||||
|
racc (~> 1.4)
|
||||||
|
nokogiri (1.18.8-x86_64-linux-gnu)
|
||||||
|
racc (~> 1.4)
|
||||||
|
nokogiri (1.18.8-x86_64-linux-musl)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
openxml-docx (0.11.5)
|
openxml-docx (0.11.5)
|
||||||
nokogiri
|
nokogiri
|
||||||
|
|
@ -189,76 +205,83 @@ GEM
|
||||||
openxml-drawingml (0.3.1)
|
openxml-drawingml (0.3.1)
|
||||||
nokogiri
|
nokogiri
|
||||||
openxml-package (~> 0.3.2)
|
openxml-package (~> 0.3.2)
|
||||||
openxml-package (0.3.4)
|
openxml-package (0.3.5)
|
||||||
nokogiri
|
nokogiri
|
||||||
ox
|
ox
|
||||||
rubyzip
|
rubyzip (~> 2.3)
|
||||||
ox (2.14.18)
|
ox (2.14.22)
|
||||||
pagy (9.0.2)
|
bigdecimal (>= 3.0)
|
||||||
|
pagy (9.3.4)
|
||||||
pandoc-ruby (2.1.10)
|
pandoc-ruby (2.1.10)
|
||||||
parallel (1.25.1)
|
parallel (1.27.0)
|
||||||
parser (3.3.4.0)
|
parser (3.3.8.0)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
racc
|
racc
|
||||||
pdf-core (0.10.0)
|
pdf-core (0.10.0)
|
||||||
|
pp (0.6.2)
|
||||||
|
prettyprint
|
||||||
prawn (2.5.0)
|
prawn (2.5.0)
|
||||||
matrix (~> 0.4)
|
matrix (~> 0.4)
|
||||||
pdf-core (~> 0.10.0)
|
pdf-core (~> 0.10.0)
|
||||||
ttfunk (~> 1.8)
|
ttfunk (~> 1.8)
|
||||||
prawn-markup (1.0.0)
|
prawn-markup (1.1.0)
|
||||||
nokogiri
|
nokogiri
|
||||||
prawn
|
prawn
|
||||||
prawn-table
|
prawn-table
|
||||||
prawn-rails (1.4.2)
|
prawn-rails (1.6.0)
|
||||||
actionview (>= 3.1.0)
|
actionview (>= 3.1.0)
|
||||||
|
activesupport (>= 3.1.0)
|
||||||
prawn
|
prawn
|
||||||
prawn-table
|
prawn-table
|
||||||
prawn-table (0.2.2)
|
prawn-table (0.2.2)
|
||||||
prawn (>= 1.3.0, < 3.0.0)
|
prawn (>= 1.3.0, < 3.0.0)
|
||||||
prism (1.2.0)
|
prettyprint (0.2.0)
|
||||||
|
prism (1.4.0)
|
||||||
propshaft (1.1.0)
|
propshaft (1.1.0)
|
||||||
actionpack (>= 7.0.0)
|
actionpack (>= 7.0.0)
|
||||||
activesupport (>= 7.0.0)
|
activesupport (>= 7.0.0)
|
||||||
rack
|
rack
|
||||||
railties (>= 7.0.0)
|
railties (>= 7.0.0)
|
||||||
psych (5.1.2)
|
psych (5.2.6)
|
||||||
|
date
|
||||||
stringio
|
stringio
|
||||||
public_suffix (6.0.0)
|
public_suffix (6.0.2)
|
||||||
puma (6.4.2)
|
puma (6.6.0)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
racc (1.8.0)
|
raabro (1.4.0)
|
||||||
rack (3.1.7)
|
racc (1.8.1)
|
||||||
rack-session (2.0.0)
|
rack (3.1.14)
|
||||||
|
rack-session (2.1.1)
|
||||||
|
base64 (>= 0.1.0)
|
||||||
rack (>= 3.0.0)
|
rack (>= 3.0.0)
|
||||||
rack-test (2.1.0)
|
rack-test (2.2.0)
|
||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rackup (2.1.0)
|
rackup (2.2.1)
|
||||||
rack (>= 3)
|
rack (>= 3)
|
||||||
webrick (~> 1.8)
|
rails (8.0.2)
|
||||||
rails (8.0.0)
|
actioncable (= 8.0.2)
|
||||||
actioncable (= 8.0.0)
|
actionmailbox (= 8.0.2)
|
||||||
actionmailbox (= 8.0.0)
|
actionmailer (= 8.0.2)
|
||||||
actionmailer (= 8.0.0)
|
actionpack (= 8.0.2)
|
||||||
actionpack (= 8.0.0)
|
actiontext (= 8.0.2)
|
||||||
actiontext (= 8.0.0)
|
actionview (= 8.0.2)
|
||||||
actionview (= 8.0.0)
|
activejob (= 8.0.2)
|
||||||
activejob (= 8.0.0)
|
activemodel (= 8.0.2)
|
||||||
activemodel (= 8.0.0)
|
activerecord (= 8.0.2)
|
||||||
activerecord (= 8.0.0)
|
activestorage (= 8.0.2)
|
||||||
activestorage (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 8.0.0)
|
railties (= 8.0.2)
|
||||||
rails-dom-testing (2.2.0)
|
rails-dom-testing (2.2.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
minitest
|
minitest
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.6.0)
|
rails-html-sanitizer (1.6.2)
|
||||||
loofah (~> 2.21)
|
loofah (~> 2.21)
|
||||||
nokogiri (~> 1.14)
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||||
railties (8.0.0)
|
railties (8.0.2)
|
||||||
actionpack (= 8.0.0)
|
actionpack (= 8.0.2)
|
||||||
activesupport (= 8.0.0)
|
activesupport (= 8.0.2)
|
||||||
irb (~> 1.13)
|
irb (~> 1.13)
|
||||||
rackup (>= 1.0.0)
|
rackup (>= 1.0.0)
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
|
|
@ -266,62 +289,62 @@ GEM
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
rake (13.2.1)
|
rake (13.2.1)
|
||||||
rbs (3.6.1)
|
rbs (3.9.4)
|
||||||
logger
|
logger
|
||||||
rdoc (6.7.0)
|
rdoc (6.13.1)
|
||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
regexp_parser (2.9.2)
|
regexp_parser (2.10.0)
|
||||||
reline (0.5.9)
|
reline (0.6.1)
|
||||||
io-console (~> 0.5)
|
io-console (~> 0.5)
|
||||||
rexml (3.3.2)
|
rexml (3.4.1)
|
||||||
strscan
|
rubocop (1.75.6)
|
||||||
rubocop (1.65.0)
|
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (>= 3.17.0)
|
language_server-protocol (~> 3.17.0.2)
|
||||||
|
lint_roller (~> 1.1.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 3.3.0.2)
|
parser (>= 3.3.0.2)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
regexp_parser (>= 2.4, < 3.0)
|
regexp_parser (>= 2.9.3, < 3.0)
|
||||||
rexml (>= 3.2.5, < 4.0)
|
rubocop-ast (>= 1.44.0, < 2.0)
|
||||||
rubocop-ast (>= 1.31.1, < 2.0)
|
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (>= 2.4.0, < 3.0)
|
unicode-display_width (>= 2.4.0, < 4.0)
|
||||||
rubocop-ast (1.31.3)
|
rubocop-ast (1.44.1)
|
||||||
parser (>= 3.3.1.0)
|
parser (>= 3.3.7.2)
|
||||||
rubocop-capybara (2.21.0)
|
prism (~> 1.4)
|
||||||
rubocop (~> 1.41)
|
rubocop-capybara (2.22.1)
|
||||||
rubocop-minitest (0.35.1)
|
lint_roller (~> 1.1)
|
||||||
rubocop (>= 1.61, < 2.0)
|
rubocop (~> 1.72, >= 1.72.1)
|
||||||
rubocop-ast (>= 1.31.1, < 2.0)
|
rubocop-performance (1.25.0)
|
||||||
rubocop-performance (1.21.1)
|
lint_roller (~> 1.1)
|
||||||
rubocop (>= 1.48.1, < 2.0)
|
rubocop (>= 1.75.0, < 2.0)
|
||||||
rubocop-ast (>= 1.31.1, < 2.0)
|
rubocop-ast (>= 1.38.0, < 2.0)
|
||||||
rubocop-rails (2.25.1)
|
rubocop-rails (2.31.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
|
lint_roller (~> 1.1)
|
||||||
rack (>= 1.1)
|
rack (>= 1.1)
|
||||||
rubocop (>= 1.33.0, < 2.0)
|
rubocop (>= 1.75.0, < 2.0)
|
||||||
rubocop-ast (>= 1.31.1, < 2.0)
|
rubocop-ast (>= 1.38.0, < 2.0)
|
||||||
rubocop-rails-omakase (1.0.0)
|
rubocop-rails-omakase (1.1.0)
|
||||||
rubocop
|
rubocop (>= 1.72)
|
||||||
rubocop-minitest
|
rubocop-performance (>= 1.24)
|
||||||
rubocop-performance
|
rubocop-rails (>= 2.30)
|
||||||
rubocop-rails
|
ruby-lsp (0.23.20)
|
||||||
ruby-lsp (0.20.1)
|
|
||||||
language_server-protocol (~> 3.17.0)
|
language_server-protocol (~> 3.17.0)
|
||||||
prism (>= 1.2, < 2.0)
|
prism (>= 1.2, < 2.0)
|
||||||
rbs (>= 3, < 4)
|
rbs (>= 3, < 4)
|
||||||
sorbet-runtime (>= 0.5.10782)
|
sorbet-runtime (>= 0.5.10782)
|
||||||
ruby-lsp-rails (0.3.21)
|
ruby-lsp-rails (0.4.3)
|
||||||
ruby-lsp (>= 0.20.0, < 0.21.0)
|
ruby-lsp (>= 0.23.18, < 0.24.0)
|
||||||
ruby-progressbar (1.13.0)
|
ruby-progressbar (1.13.0)
|
||||||
ruby-vips (2.2.1)
|
ruby-vips (2.2.3)
|
||||||
ffi (~> 1.12)
|
ffi (~> 1.12)
|
||||||
rubyzip (2.3.2)
|
logger
|
||||||
|
rubyzip (2.4.1)
|
||||||
sablon (0.4.1)
|
sablon (0.4.1)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
rubyzip (>= 1.3.0)
|
rubyzip (>= 1.3.0)
|
||||||
securerandom (0.3.1)
|
securerandom (0.4.1)
|
||||||
selenium-webdriver (4.23.0)
|
selenium-webdriver (4.32.0)
|
||||||
base64 (~> 0.2)
|
base64 (~> 0.2)
|
||||||
logger (~> 1.4)
|
logger (~> 1.4)
|
||||||
rexml (~> 3.2, >= 3.2.5)
|
rexml (~> 3.2, >= 3.2.5)
|
||||||
|
|
@ -330,53 +353,64 @@ GEM
|
||||||
slim (5.2.1)
|
slim (5.2.1)
|
||||||
temple (~> 0.10.0)
|
temple (~> 0.10.0)
|
||||||
tilt (>= 2.1.0)
|
tilt (>= 2.1.0)
|
||||||
sorbet-runtime (0.5.11625)
|
solid_queue (1.1.5)
|
||||||
sqlite3 (2.2.0-aarch64-linux-gnu)
|
activejob (>= 7.1)
|
||||||
sqlite3 (2.2.0-arm-linux-gnu)
|
activerecord (>= 7.1)
|
||||||
sqlite3 (2.2.0-arm64-darwin)
|
concurrent-ruby (>= 1.3.1)
|
||||||
sqlite3 (2.2.0-x86-linux-gnu)
|
fugit (~> 1.11.0)
|
||||||
sqlite3 (2.2.0-x86_64-darwin)
|
railties (>= 7.1)
|
||||||
sqlite3 (2.2.0-x86_64-linux-gnu)
|
thor (~> 1.3.1)
|
||||||
stimulus-rails (1.3.3)
|
sorbet-runtime (0.5.12109)
|
||||||
|
sqlite3 (2.6.0-aarch64-linux-gnu)
|
||||||
|
sqlite3 (2.6.0-aarch64-linux-musl)
|
||||||
|
sqlite3 (2.6.0-arm-linux-gnu)
|
||||||
|
sqlite3 (2.6.0-arm-linux-musl)
|
||||||
|
sqlite3 (2.6.0-arm64-darwin)
|
||||||
|
sqlite3 (2.6.0-x86_64-darwin)
|
||||||
|
sqlite3 (2.6.0-x86_64-linux-gnu)
|
||||||
|
sqlite3 (2.6.0-x86_64-linux-musl)
|
||||||
|
stimulus-rails (1.3.4)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
stringio (3.1.1)
|
stringio (3.1.7)
|
||||||
strscan (3.1.0)
|
|
||||||
temple (0.10.3)
|
temple (0.10.3)
|
||||||
thor (1.3.1)
|
thor (1.3.2)
|
||||||
tilt (2.4.0)
|
tilt (2.6.0)
|
||||||
timeout (0.4.1)
|
timeout (0.4.3)
|
||||||
ttfunk (1.8.0)
|
ttfunk (1.8.0)
|
||||||
bigdecimal (~> 3.1)
|
bigdecimal (~> 3.1)
|
||||||
turbo-rails (2.0.5)
|
turbo-rails (2.0.13)
|
||||||
actionpack (>= 6.0.0)
|
actionpack (>= 7.1.0)
|
||||||
activejob (>= 6.0.0)
|
railties (>= 7.1.0)
|
||||||
railties (>= 6.0.0)
|
|
||||||
tzinfo (2.0.6)
|
tzinfo (2.0.6)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
unicode-display_width (2.5.0)
|
unicode-display_width (3.1.4)
|
||||||
uri (1.0.1)
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
||||||
useragent (0.16.10)
|
unicode-emoji (4.0.4)
|
||||||
|
uri (1.0.3)
|
||||||
|
useragent (0.16.11)
|
||||||
web-console (4.2.1)
|
web-console (4.2.1)
|
||||||
actionview (>= 6.0.0)
|
actionview (>= 6.0.0)
|
||||||
activemodel (>= 6.0.0)
|
activemodel (>= 6.0.0)
|
||||||
bindex (>= 0.4.0)
|
bindex (>= 0.4.0)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
webrick (1.8.1)
|
|
||||||
websocket (1.2.11)
|
websocket (1.2.11)
|
||||||
websocket-driver (0.7.6)
|
websocket-driver (0.7.7)
|
||||||
|
base64
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
zeitwerk (2.6.16)
|
zeitwerk (2.7.2)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
aarch64-linux
|
aarch64-linux-gnu
|
||||||
arm-linux
|
aarch64-linux-musl
|
||||||
|
arm-linux-gnu
|
||||||
|
arm-linux-musl
|
||||||
arm64-darwin
|
arm64-darwin
|
||||||
x86-linux
|
|
||||||
x86_64-darwin
|
x86_64-darwin
|
||||||
x86_64-linux
|
x86_64-linux-gnu
|
||||||
|
x86_64-linux-musl
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
bcrypt (~> 3.1.7)
|
bcrypt (~> 3.1.7)
|
||||||
|
|
@ -388,6 +422,7 @@ DEPENDENCIES
|
||||||
caxlsx_rails
|
caxlsx_rails
|
||||||
cssbundling-rails
|
cssbundling-rails
|
||||||
debug
|
debug
|
||||||
|
deepl-rb
|
||||||
html2slim
|
html2slim
|
||||||
image_processing (~> 1.2)
|
image_processing (~> 1.2)
|
||||||
jbuilder
|
jbuilder
|
||||||
|
|
@ -409,14 +444,12 @@ DEPENDENCIES
|
||||||
sablon
|
sablon
|
||||||
selenium-webdriver
|
selenium-webdriver
|
||||||
slim
|
slim
|
||||||
|
solid_queue
|
||||||
sqlite3 (>= 2.1)
|
sqlite3 (>= 2.1)
|
||||||
stimulus-rails
|
stimulus-rails
|
||||||
turbo-rails
|
turbo-rails
|
||||||
tzinfo-data
|
tzinfo-data
|
||||||
web-console
|
web-console
|
||||||
|
|
||||||
RUBY VERSION
|
|
||||||
ruby 3.2.5p208
|
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.5.15
|
2.6.2
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0
|
web: RUBY_DEBUG_OPEN=true bin/rails server -b 0
|
||||||
js: yarn build --watch
|
js: yarn build --watch=forever
|
||||||
css: yarn watch:css
|
css: yarn watch:css
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,7 @@
|
||||||
|
|
||||||
`rails new -n a11yist -d sqlite3 --skip-action-mailbox --css bootstrap --js esbuild .`
|
`rails new -n a11yist -d sqlite3 --skip-action-mailbox --css bootstrap --js esbuild .`
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To [install](readme)
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
BIN
app/assets/images/logo-apfelschule_xs.png
Normal file
BIN
app/assets/images/logo-apfelschule_xs.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -28,13 +28,8 @@ $enable-rounded: false;
|
||||||
|
|
||||||
@import 'bootstrap/scss/bootstrap';
|
@import 'bootstrap/scss/bootstrap';
|
||||||
|
|
||||||
@font-face {
|
$lg-path-images: "";
|
||||||
font-display: block;
|
$bootstrap-icons-font-dir: "";
|
||||||
font-family: "bootstrap-icons";
|
|
||||||
src: url("./bootstrap-icons.woff2") format("woff2"),
|
|
||||||
url("./bootstrap-icons.woff") format("woff");
|
|
||||||
}
|
|
||||||
|
|
||||||
@import 'bootstrap-icons/font/bootstrap-icons';
|
@import 'bootstrap-icons/font/bootstrap-icons';
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,6 +47,10 @@ $enable-rounded: false;
|
||||||
|
|
||||||
@import "trix/dist/trix";
|
@import "trix/dist/trix";
|
||||||
|
|
||||||
|
$lg-path-fonts: "";
|
||||||
|
|
||||||
|
@import "lightgallery/scss/lightgallery";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
|
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
|
||||||
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
|
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
|
||||||
|
|
@ -164,4 +163,5 @@ trix-toolbar .trix-dialog--link {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
@import "./layout";
|
@import "./layout";
|
||||||
|
@import "./dropdown";
|
||||||
67
app/assets/stylesheets/dropdown.scss
Normal file
67
app/assets/stylesheets/dropdown.scss
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
.details-dropdown {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide The disclosure widget: */
|
||||||
|
.details-dropdown summary {
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.details-dropdown[open] summary {
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
i {
|
||||||
|
|
||||||
|
color: var(--bs-body-color)
|
||||||
|
}
|
||||||
|
/* border-left: solid 1px $secondary; */
|
||||||
|
/* border-top: solid 1px $secondary; */
|
||||||
|
/* border-right: solid 1px $secondary; */
|
||||||
|
}
|
||||||
|
.details-dropdown[open] {
|
||||||
|
background-color: $secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detache details content */
|
||||||
|
.details-dropdown .details-dropdown-content {
|
||||||
|
border: solid 1px $secondary;
|
||||||
|
position: absolute;
|
||||||
|
min-inline-size: max-content;
|
||||||
|
z-index: 2000;
|
||||||
|
|
||||||
|
/* In case the details-dropdown should open to the left: */
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Closing the details-dropdown on clicking anywhere else */
|
||||||
|
.details-dropdown[open] summary::before {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
content: "";
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Visual styles for your details-dropdown: */
|
||||||
|
.details-dropdown .details-dropdown-trigger {
|
||||||
|
/* your look and feel here */
|
||||||
|
}
|
||||||
|
|
||||||
|
.details-dropdown .details-dropdown-content {
|
||||||
|
/* your look and feel here */
|
||||||
|
}
|
||||||
|
|
||||||
|
form.no-padding {
|
||||||
|
button {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li.list-group-item-danger:hover {
|
||||||
|
button {
|
||||||
|
color: var(--bs-body-color) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,37 +20,6 @@ $tertiary-dark-active-open: $gray-600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Fix trix dark mode
|
|
||||||
// .trix-button-row {
|
|
||||||
// .trix-button-group {
|
|
||||||
// border: var(--bs-border-width) solid var(--bs-border-color);
|
|
||||||
|
|
||||||
// .trix-button {
|
|
||||||
// border: 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [data-bs-theme=dark] {
|
|
||||||
// .trix-button-row {
|
|
||||||
// .trix-button-group {
|
|
||||||
// .trix-button {
|
|
||||||
// background-color: transparent;
|
|
||||||
// filter: invert(100%);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // end fix trix dark mode
|
|
||||||
|
|
||||||
// .trix-content pre {
|
|
||||||
// background-color: var(--bs-secondary-bg);
|
|
||||||
// color: var(--bs-secondary-color);
|
|
||||||
// border: var(--bs-border-width) solid var(--bs-border-color);
|
|
||||||
// border-radius: var(--bs-border-radius);
|
|
||||||
// padding: var(--bs-padding);
|
|
||||||
// }
|
|
||||||
|
|
||||||
.hover-row:hover {
|
.hover-row:hover {
|
||||||
background-color: var(--bs-tertiary-bg);
|
background-color: var(--bs-tertiary-bg);
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +60,10 @@ $tertiary-dark-active-open: $gray-600;
|
||||||
.page_nav nav ul {
|
.page_nav nav ul {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
line-height: 2rem;
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--bs-text);
|
color: var(--bs-text);
|
||||||
|
|
@ -223,7 +195,15 @@ details.tree[open]>summary::before {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
details.success_criterion:last-child {
|
||||||
|
border-bottom: solid 1px $tertiary;
|
||||||
|
}
|
||||||
|
|
||||||
details.success_criterion {
|
details.success_criterion {
|
||||||
|
border-left: solid 1px $tertiary;
|
||||||
|
border-right: solid 0px $tertiary;
|
||||||
|
border-top: solid 0px $tertiary;
|
||||||
|
|
||||||
summary:hover {
|
summary:hover {
|
||||||
background-color: $tertiary-hover;
|
background-color: $tertiary-hover;
|
||||||
|
|
||||||
|
|
@ -239,6 +219,7 @@ details.success_criterion {
|
||||||
>.content {
|
>.content {
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -253,26 +234,36 @@ details.success_criterion {
|
||||||
|
|
||||||
|
|
||||||
details.success_criterion[open] {
|
details.success_criterion[open] {
|
||||||
border: solid 1px $tertiary;
|
/* border: solid 1px $tertiary; */
|
||||||
|
|
||||||
summary {
|
>summary {
|
||||||
background-color: $tertiary;
|
background-color: $tertiary;
|
||||||
}
|
}
|
||||||
|
|
||||||
summary:hover {
|
>summary:hover {
|
||||||
background-color: $tertiary-active-hover;
|
background-color: $tertiary-active-hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include color-mode(dark) {
|
@include color-mode(dark) {
|
||||||
details.success_criterion[open] {
|
details.success_criterion {
|
||||||
border: solid 1px $tertiary-dark;
|
border-left: solid 1px $tertiary-dark;
|
||||||
|
border-right: solid 1px $tertiary-dark;
|
||||||
|
border-top: solid 1px $tertiary-dark;
|
||||||
|
}
|
||||||
|
|
||||||
summary {
|
details.success_criterion:last-child {
|
||||||
|
border-bottom: solid 1px $tertiary-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
details.success_criterion[open] {
|
||||||
|
/* border: solid 1px $tertiary-dark; */
|
||||||
|
|
||||||
|
>summary {
|
||||||
background-color: $tertiary-dark;
|
background-color: $tertiary-dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
summary:hover {
|
>summary:hover {
|
||||||
background-color: $tertiary-dark-active-open;
|
background-color: $tertiary-dark-active-open;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -326,4 +317,65 @@ details[open] {
|
||||||
|
|
||||||
.sortable-ghost {
|
.sortable-ghost {
|
||||||
border: solid 3px $primary !important;
|
border: solid 3px $primary !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog-animation-time: 0.5s;
|
||||||
|
$dialog-animation-start-state: scaleX(1);
|
||||||
|
$dialog-animation-end-state: scaleX(1);
|
||||||
|
/* dialog::backdrop { */
|
||||||
|
/* background-color: white; */
|
||||||
|
/* opacity: 0.75; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
/* Open state of the dialog */
|
||||||
|
dialog[open] {
|
||||||
|
opacity: 1;
|
||||||
|
transform: $dialog-animation-end-state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Closed state of the dialog */
|
||||||
|
dialog {
|
||||||
|
opacity: 0;
|
||||||
|
transform: $dialog-animation-start-state;
|
||||||
|
transition:
|
||||||
|
opacity $dialog-animation-time ease-out,
|
||||||
|
transform $dialog-animation-time ease-out,
|
||||||
|
overlay $dialog-animation-time ease-out allow-discrete,
|
||||||
|
display $dialog-animation-time ease-out allow-discrete;
|
||||||
|
/* Equivalent to
|
||||||
|
transition: all $dialog-animation-time allow-discrete; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Before-open state */
|
||||||
|
/* Needs to be after the previous dialog[open] rule to take effect,
|
||||||
|
as the specificity is the same */
|
||||||
|
@starting-style {
|
||||||
|
dialog[open] {
|
||||||
|
opacity: 0;
|
||||||
|
transform: $dialog-animation-start-state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transition the :backdrop when the dialog modal is promoted to the top layer */
|
||||||
|
dialog::backdrop {
|
||||||
|
background-color: rgb(0 0 0 / 75%);
|
||||||
|
transition:
|
||||||
|
display $dialog-animation-time allow-discrete,
|
||||||
|
overlay $dialog-animation-time allow-discrete,
|
||||||
|
background-color $dialog-animation-time;
|
||||||
|
/* Equivalent to
|
||||||
|
transition: all $dialog-animation-time allow-discrete; */
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[open]::backdrop {
|
||||||
|
background-color: rgb(0 0 0 / 75%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This starting-style rule cannot be nested inside the above selector
|
||||||
|
because the nesting selector cannot represent pseudo-elements. */
|
||||||
|
|
||||||
|
@starting-style {
|
||||||
|
dialog[open]::backdrop {
|
||||||
|
background-color: rgb(0 0 0 / 0%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,9 +22,9 @@ class ApplicationController < ActionController::Base
|
||||||
path: :root
|
path: :root
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: Report.model_name.human(count: 2),
|
label: Project.model_name.human(count: 2),
|
||||||
icon: :'journal-text',
|
icon: :'folder',
|
||||||
path: :reports },
|
path: :projects },
|
||||||
{
|
{
|
||||||
label: I18n.t("backoffice"),
|
label: I18n.t("backoffice"),
|
||||||
icon: :gear,
|
icon: :gear,
|
||||||
|
|
@ -32,7 +32,8 @@ class ApplicationController < ActionController::Base
|
||||||
active: %w[backoffice checklists checks links link_categories].include?(controller_name) },
|
active: %w[backoffice checklists checks links link_categories].include?(controller_name) },
|
||||||
{
|
{
|
||||||
label: "Konto",
|
label: "Konto",
|
||||||
path: profile_path
|
path: profile_path,
|
||||||
|
icon: "person-circle"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
|
|
@ -50,4 +51,8 @@ class ApplicationController < ActionController::Base
|
||||||
def initialize_sidebar_items
|
def initialize_sidebar_items
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_modal(action: action_name)
|
||||||
|
render action, layout: "modal" if turbo_frame_request_id == "modal"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ class ChecksController < ApplicationController
|
||||||
|
|
||||||
# Only allow a list of trusted parameters through.
|
# Only allow a list of trusted parameters through.
|
||||||
def check_params
|
def check_params
|
||||||
params.require(:check).permit(:principle_id,
|
params.require(:check).permit(:guideline_id,
|
||||||
:number,
|
:number,
|
||||||
:name_de,
|
:name_de,
|
||||||
:name_en,
|
:name_en,
|
||||||
|
|
@ -95,7 +95,9 @@ class ChecksController < ApplicationController
|
||||||
:applicable_to_analogue,
|
:applicable_to_analogue,
|
||||||
:applicable_to_document,
|
:applicable_to_document,
|
||||||
:applicable_to_non_web,
|
:applicable_to_non_web,
|
||||||
:external_number,
|
:external_number_1,
|
||||||
|
:external_number_2,
|
||||||
|
:external_number_3,
|
||||||
:external_url,
|
:external_url,
|
||||||
:conformity_level,
|
:conformity_level,
|
||||||
:conformity_notice_de,
|
:conformity_notice_de,
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ module Authentication
|
||||||
resume_session || request_authentication
|
resume_session || request_authentication
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def resume_session
|
def resume_session
|
||||||
Current.session ||= find_session_by_cookie
|
Current.session ||= find_session_by_cookie
|
||||||
end
|
end
|
||||||
|
|
@ -30,7 +29,6 @@ module Authentication
|
||||||
Session.find_by(id: cookies.signed[:session_id])
|
Session.find_by(id: cookies.signed[:session_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def request_authentication
|
def request_authentication
|
||||||
session[:return_to_after_authenticating] = request.url
|
session[:return_to_after_authenticating] = request.url
|
||||||
redirect_to new_session_path
|
redirect_to new_session_path
|
||||||
|
|
@ -40,7 +38,6 @@ module Authentication
|
||||||
session.delete(:return_to_after_authenticating) || root_url
|
session.delete(:return_to_after_authenticating) || root_url
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def start_new_session_for(user)
|
def start_new_session_for(user)
|
||||||
user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session|
|
user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session|
|
||||||
Current.session = session
|
Current.session = session
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ module BackofficeMenu
|
||||||
[
|
[
|
||||||
{ label: "Einstellungen", icon: :sliders, path: :backoffice },
|
{ label: "Einstellungen", icon: :sliders, path: :backoffice },
|
||||||
{ label: Checklist.model_name.human(count: 2), icon: :'list-check', path: :checklists },
|
{ label: Checklist.model_name.human(count: 2), icon: :'list-check', path: :checklists },
|
||||||
|
{ label: Guideline.model_name.human(count: 2), icon: :'rulers', path: :guidelines },
|
||||||
{ label: Check.model_name.human(count: 2), icon: :check2, path: :checks },
|
{ label: Check.model_name.human(count: 2), icon: :check2, path: :checks },
|
||||||
{ label: Link.model_name.human(count: 2), icon: :link, path: :links },
|
{ label: Link.model_name.human(count: 2), icon: :link, path: :links },
|
||||||
{ label: LinkCategory.model_name.human(count: 2), icon: :folder, path: :link_categories } ]
|
{ label: LinkCategory.model_name.human(count: 2), icon: :folder, path: :link_categories } ]
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ class ElementsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /elements/1/edit
|
# GET /elements/1/edit
|
||||||
def edit; end
|
def edit
|
||||||
|
render_modal
|
||||||
|
end
|
||||||
|
|
||||||
# POST /elements
|
# POST /elements
|
||||||
def create
|
def create
|
||||||
|
|
@ -87,6 +89,6 @@ class ElementsController < ApplicationController
|
||||||
|
|
||||||
# Only allow a list of trusted parameters through.
|
# Only allow a list of trusted parameters through.
|
||||||
def element_params
|
def element_params
|
||||||
params.require(:element).permit(:page_id, :title, :description, :position)
|
params.require(:element).permit(:page_id, :title, :description, :position, :screenshot)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
58
app/controllers/guidelines_controller.rb
Normal file
58
app/controllers/guidelines_controller.rb
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
class GuidelinesController < BackofficeController
|
||||||
|
before_action :set_guideline, only: %i[ show edit update destroy ]
|
||||||
|
|
||||||
|
# GET /guidelines
|
||||||
|
def index
|
||||||
|
@guidelines = Guideline.all
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /guidelines/1
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /guidelines/new
|
||||||
|
def new
|
||||||
|
@guideline = Guideline.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /guidelines/1/edit
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST /guidelines
|
||||||
|
def create
|
||||||
|
@guideline = Guideline.new(guideline_params)
|
||||||
|
|
||||||
|
if @guideline.save
|
||||||
|
redirect_to @guideline, notice: "Guideline was successfully created."
|
||||||
|
else
|
||||||
|
render :new, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# PATCH/PUT /guidelines/1
|
||||||
|
def update
|
||||||
|
if @guideline.update(guideline_params)
|
||||||
|
redirect_to @guideline, notice: "Guideline was successfully updated.", status: :see_other
|
||||||
|
else
|
||||||
|
render :edit, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# DELETE /guidelines/1
|
||||||
|
def destroy
|
||||||
|
@guideline.destroy!
|
||||||
|
redirect_to guidelines_url, notice: "Guideline was successfully destroyed.", status: :see_other
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Use callbacks to share common setup or constraints between actions.
|
||||||
|
def set_guideline
|
||||||
|
@guideline = Guideline.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Only allow a list of trusted parameters through.
|
||||||
|
def guideline_params
|
||||||
|
params.require(:guideline).permit(:principle_id, :number, :name_de, :name_en, :description_de, :description_en)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -20,11 +20,6 @@ class HomeController < ApplicationController
|
||||||
path: profile_path,
|
path: profile_path,
|
||||||
active: action_name == "profile"
|
active: action_name == "profile"
|
||||||
},
|
},
|
||||||
# {
|
|
||||||
# label: "Passwort ändern",
|
|
||||||
# path: new_password_path,
|
|
||||||
# icon: :lock
|
|
||||||
# },
|
|
||||||
{
|
{
|
||||||
label: "Logout",
|
label: "Logout",
|
||||||
icon: :"box-arrow-right",
|
icon: :"box-arrow-right",
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ class PagesController < ApplicationController
|
||||||
|
|
||||||
# GET /pages/1/edit
|
# GET /pages/1/edit
|
||||||
def edit
|
def edit
|
||||||
|
render_modal
|
||||||
end
|
end
|
||||||
|
|
||||||
# POST /pages
|
# POST /pages
|
||||||
|
|
|
||||||
62
app/controllers/projects_controller.rb
Normal file
62
app/controllers/projects_controller.rb
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
class ProjectsController < ApplicationController
|
||||||
|
before_action :set_project, only: %i[ show edit update destroy ]
|
||||||
|
|
||||||
|
# GET /projects
|
||||||
|
def index
|
||||||
|
@projects = Project.all
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /projects/1
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /projects/new
|
||||||
|
def new
|
||||||
|
@project = Project.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /projects/1/edit
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST /projects
|
||||||
|
def create
|
||||||
|
@project = if params[:copy_from_id]
|
||||||
|
Project.find(params[:copy_from_id]).dup
|
||||||
|
else
|
||||||
|
Project.new(project_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @project.save
|
||||||
|
redirect_to @project, notice: "Project was successfully created."
|
||||||
|
else
|
||||||
|
render :new, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# PATCH/PUT /projects/1
|
||||||
|
def update
|
||||||
|
if @project.update(project_params)
|
||||||
|
redirect_to @project, notice: "Project was successfully updated.", status: :see_other
|
||||||
|
else
|
||||||
|
render :edit, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# DELETE /projects/1
|
||||||
|
def destroy
|
||||||
|
@project.destroy!
|
||||||
|
redirect_to projects_url, notice: "Project was successfully destroyed.", status: :see_other
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Use callbacks to share common setup or constraints between actions.
|
||||||
|
def set_project
|
||||||
|
@project = Project.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Only allow a list of trusted parameters through.
|
||||||
|
def project_params
|
||||||
|
params.require(:project).permit(:name, :details)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ReportsController < ApplicationController
|
class ReportsController < ApplicationController
|
||||||
|
before_action :set_project, only: %i[index new create]
|
||||||
before_action :set_report, only: %i[show edit update destroy work]
|
before_action :set_report, only: %i[show edit update destroy work]
|
||||||
|
|
||||||
# GET /reports
|
# GET /reports
|
||||||
def index
|
def index
|
||||||
@reports = Report.all
|
@reports = @project.reports
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /reports/1
|
# GET /reports/1
|
||||||
|
|
@ -85,7 +86,7 @@ class ReportsController < ApplicationController
|
||||||
|
|
||||||
# GET /reports/new
|
# GET /reports/new
|
||||||
def new
|
def new
|
||||||
@report = Report.new
|
@report = Report.new(project_id: @project.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /reports/1/edit
|
# GET /reports/1/edit
|
||||||
|
|
@ -93,10 +94,45 @@ class ReportsController < ApplicationController
|
||||||
|
|
||||||
# POST /reports
|
# POST /reports
|
||||||
def create
|
def create
|
||||||
@report = Report.new(report_params)
|
success = if params[:copy_from_id]
|
||||||
|
original = Report.find(params[:copy_from_id])
|
||||||
|
@report = original.dup
|
||||||
|
@report.pages = original.pages.map do |page|
|
||||||
|
page.dup.tap do |p|
|
||||||
|
p.elements = page.elements.map do |element|
|
||||||
|
element.dup.tap do |e|
|
||||||
|
e.success_criteria = element.success_criteria.map do |sc|
|
||||||
|
csc = sc.dup
|
||||||
|
SuccessCriterion.rich_text_association_names
|
||||||
|
.map { _1.to_s.sub(/^rich_text_/, "") }
|
||||||
|
.each do |a|
|
||||||
|
csc.send("#{a}=", sc.send(a).dup)
|
||||||
|
end
|
||||||
|
csc
|
||||||
|
end
|
||||||
|
e.screenshot = element.screenshot&.dup
|
||||||
|
Element.rich_text_association_names
|
||||||
|
.map { _1.to_s.sub(/^rich_text_/, "") }
|
||||||
|
.each do |a|
|
||||||
|
e.send("#{a}=", element.send(a).dup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Page.rich_text_association_names
|
||||||
|
.map { _1.to_s.sub(/^rich_text_/, "") }
|
||||||
|
.each do |a|
|
||||||
|
p.send("#{a}=", page.send(a).dup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@report.save
|
||||||
|
else
|
||||||
|
@report = Report.new(report_params.merge(project_id: @project.id))
|
||||||
|
@report.save
|
||||||
|
end
|
||||||
|
|
||||||
if @report.save
|
if success
|
||||||
redirect_to @report, notice: "Report was successfully created."
|
redirect_to @report.reload, notice: "Report was successfully created."
|
||||||
else
|
else
|
||||||
render :new, status: :unprocessable_entity
|
render :new, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
@ -114,7 +150,7 @@ class ReportsController < ApplicationController
|
||||||
# DELETE /reports/1
|
# DELETE /reports/1
|
||||||
def destroy
|
def destroy
|
||||||
@report.destroy!
|
@report.destroy!
|
||||||
redirect_to reports_url, notice: "Report was successfully destroyed.", status: :see_other
|
redirect_to project_url(@report.project), notice: "Report was successfully destroyed.", status: :see_other
|
||||||
end
|
end
|
||||||
|
|
||||||
def work
|
def work
|
||||||
|
|
@ -130,7 +166,7 @@ class ReportsController < ApplicationController
|
||||||
|
|
||||||
# Only allow a list of trusted parameters through.
|
# Only allow a list of trusted parameters through.
|
||||||
def report_params
|
def report_params
|
||||||
params.require(:report).permit(:name, :comment, :url)
|
params.require(:report).permit(:name, :comment, :url, :project_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def filename(report, extension: "html")
|
def filename(report, extension: "html")
|
||||||
|
|
@ -140,4 +176,8 @@ class ReportsController < ApplicationController
|
||||||
def page_param
|
def page_param
|
||||||
params[:page_id]
|
params[:page_id]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_project
|
||||||
|
@project = Project.find(params[:project_id])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
class SuccessCriteriaController < ApplicationController
|
class SuccessCriteriaController < ApplicationController
|
||||||
before_action :set_element, only: %i[new create index new_from_checklist create_from_checklist]
|
before_action :set_element, only: %i[new create index new_from_checklist create_from_checklist]
|
||||||
before_action :set_success_criterion, only: %i[show edit update destroy]
|
before_action :set_success_criterion, only: %i[show edit update destroy edit_comment]
|
||||||
|
|
||||||
# GET /success_criteria
|
# GET /success_criteria
|
||||||
def index
|
def index
|
||||||
|
|
@ -18,7 +18,9 @@ class SuccessCriteriaController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /success_criteria/1/edit
|
# GET /success_criteria/1/edit
|
||||||
def edit; end
|
def edit
|
||||||
|
render_modal()
|
||||||
|
end
|
||||||
|
|
||||||
# POST /success_criteria
|
# POST /success_criteria
|
||||||
def create
|
def create
|
||||||
|
|
@ -106,6 +108,10 @@ class SuccessCriteriaController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit_comment
|
||||||
|
render_modal()
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Use callbacks to share common setup or constraints between actions.
|
# Use callbacks to share common setup or constraints between actions.
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def safe_display(value, &block)
|
def safe_display(value, &block)
|
||||||
return unless value
|
return if value.blank?
|
||||||
|
|
||||||
yield(value)
|
yield(value)
|
||||||
end
|
end
|
||||||
|
|
@ -28,4 +28,41 @@ module ApplicationHelper
|
||||||
def current_page_displayed(page)
|
def current_page_displayed(page)
|
||||||
@current_page&.id == page.id ? "open" : nil
|
@current_page&.id == page.id ? "open" : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def turbo_stream_toast(content, alert)
|
||||||
|
turbo_stream.append("toasts", partial: "layouts/toast", locals: { content:, alert: })
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def dropdown_menu(items, klass: "")
|
||||||
|
tag.details(class: "details-dropdown #{klass}", data: { controller: "dropdown-menu" }) do
|
||||||
|
tag.summary do
|
||||||
|
tag.div(class: "details-dropdown-trigger") do
|
||||||
|
tag.div(tag.i(class: "bi bi-three-dots"), class: "btn btn-outline-body")
|
||||||
|
end
|
||||||
|
end +
|
||||||
|
tag.div(class: "details-dropdown-content bg-secondary") do
|
||||||
|
tag.div(class: "list-group") do
|
||||||
|
safe_join(items.map do |item|
|
||||||
|
c = "list-group-item list-group-item-action #{ item[:color] ? " list-group-item-#{item[:color]}" : "list-group-item-secondary"}"
|
||||||
|
text = item[:icon] ? tag.i(class: "bi bi-#{item[:icon]} me-2") + " #{item[:text]}".html_safe : item[:text]
|
||||||
|
case item[:method]
|
||||||
|
when nil, :get
|
||||||
|
link_to(text, item[:href], class: "#{c}", data: { turbo_frame: item[:turbo_frame], action: item[:action] })
|
||||||
|
else
|
||||||
|
button_to(text,
|
||||||
|
item[:href],
|
||||||
|
method: item[:method],
|
||||||
|
class: "#{c}",
|
||||||
|
data: { turbo_confirm: item[:confirm] })
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def modal?
|
||||||
|
turbo_frame_request_id == "modal"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,19 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module ElementsHelper
|
module ElementsHelper
|
||||||
|
def element_menu(element)
|
||||||
|
dropdown_menu([
|
||||||
|
{ text: "Bearbeiten",
|
||||||
|
icon: "pencil",
|
||||||
|
href: edit_element_path(element),
|
||||||
|
turbo_frame: "modal",
|
||||||
|
color: "body" },
|
||||||
|
{ text: "Löschen",
|
||||||
|
icon: "trash",
|
||||||
|
href: element_path(element),
|
||||||
|
color: :danger,
|
||||||
|
method: :delete,
|
||||||
|
confirm: "Bist du sicher?" } ],
|
||||||
|
klass: "ms-auto")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,27 @@
|
||||||
module PagesHelper
|
module PagesHelper
|
||||||
|
def page_menu(page)
|
||||||
|
dropdown_menu([
|
||||||
|
{
|
||||||
|
text: "Alle zu [s]",
|
||||||
|
href: "#",
|
||||||
|
action: "click->details-list#closeAll"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Alle auf [a]",
|
||||||
|
href: "#",
|
||||||
|
action: "click->details-list#openAll"
|
||||||
|
},
|
||||||
|
{ text: "Bearbeiten",
|
||||||
|
icon: "pencil",
|
||||||
|
href: edit_page_path(page),
|
||||||
|
turbo_frame: "modal",
|
||||||
|
color: "body" },
|
||||||
|
{ text: "Löschen",
|
||||||
|
icon: "trash",
|
||||||
|
href: page_path(page),
|
||||||
|
color: :danger,
|
||||||
|
method: :delete,
|
||||||
|
confirm: "Bist du sicher?" } ],
|
||||||
|
klass: "ms-auto")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
2
app/helpers/projects_helper.rb
Normal file
2
app/helpers/projects_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module ProjectsHelper
|
||||||
|
end
|
||||||
|
|
@ -25,8 +25,23 @@ module SuccessCriteriaHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def success_criterion_menu(success_criterion, show_mode = true)
|
||||||
|
dropdown_menu([
|
||||||
|
{ text: "Bearbeiten",
|
||||||
|
icon: "pencil",
|
||||||
|
href: edit_success_criterion_path(success_criterion),
|
||||||
|
turbo_frame: "modal",
|
||||||
|
color: "body" },
|
||||||
|
{ text: "Löschen",
|
||||||
|
icon: "trash",
|
||||||
|
href: success_criterion_path(success_criterion),
|
||||||
|
color: :danger,
|
||||||
|
method: :delete,
|
||||||
|
confirm: "Bist du sicher?" } ],
|
||||||
|
klass: "mt-3 ms-auto")
|
||||||
|
end
|
||||||
|
|
||||||
def success_criterion_edit_button(success_criterion, edit_mode)
|
def success_criterion_edit_button(success_criterion, edit_mode)
|
||||||
path = if success_criterion.persisted?
|
path = if success_criterion.persisted?
|
||||||
if edit_mode
|
if edit_mode
|
||||||
success_criterion
|
success_criterion
|
||||||
|
|
@ -37,9 +52,9 @@ module SuccessCriteriaHelper
|
||||||
else
|
else
|
||||||
success_criterion.element
|
success_criterion.element
|
||||||
end
|
end
|
||||||
link_to tag.i(class: "bi bi-pencil"),
|
link_to tag.i(class: "bi bi-pencil") + " Bearbeiten".html_safe,
|
||||||
path,
|
path,
|
||||||
class: "btn btn-#{edit_mode ? 'link text-warning' : 'link text-body'}"
|
class: "text-decoration-none xbtn xbtn-#{edit_mode ? 'link text-warning' : 'link text-body'}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def success_criterion_badge(content, extra_classes: "")
|
def success_criterion_badge(content, extra_classes: "")
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Entry point for the build script in your package.json
|
// Entry point for the build script in your package.json
|
||||||
import "@hotwired/turbo-rails"
|
import "@hotwired/turbo-rails"
|
||||||
import "./controllers"
|
import "./controllers"
|
||||||
import * as bootstrap from "bootstrap"
|
|
||||||
|
|
||||||
import "trix"
|
import "trix"
|
||||||
import "@rails/actiontext"
|
import "@rails/actiontext"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ export default class extends Controller {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const id = this.element.dataset["targetId"]
|
const id = this.element.dataset["targetId"]
|
||||||
const el = document.getElementById(id)
|
const el = document.getElementById(id)
|
||||||
el.querySelectorAll("details").forEach(el => {
|
el.querySelectorAll("details.success_criterion").forEach(el => {
|
||||||
el.setAttribute("open", "")
|
el.setAttribute("open", "")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ export default class extends Controller {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const id = this.element.dataset["targetId"]
|
const id = this.element.dataset["targetId"]
|
||||||
const el = document.getElementById(id)
|
const el = document.getElementById(id)
|
||||||
el.querySelectorAll("details").forEach(el => {
|
el.querySelectorAll("details.success_criterion").forEach(el => {
|
||||||
el.removeAttribute("open")
|
el.removeAttribute("open")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
app/javascript/controllers/dialog_controller.js
Normal file
53
app/javascript/controllers/dialog_controller.js
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
// app/javascript/controllers/dialog_controller.js
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
// Connects to data-controller="dialog"
|
||||||
|
export default class extends Controller {
|
||||||
|
connect() {
|
||||||
|
this.open()
|
||||||
|
console.log("connect dialog", this.element)
|
||||||
|
this.element.addEventListener("turbo:submit-end", e => {
|
||||||
|
this.submitEnd(e)
|
||||||
|
})
|
||||||
|
this.element.addEventListener("click", e => this.clickOutside(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// hide modal on successful form submission
|
||||||
|
// data-action="turbo:submit-end->turbo-modal#submitEnd"
|
||||||
|
submitEnd(e) {
|
||||||
|
if (e.detail.success) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
console.log("open dialog")
|
||||||
|
this.element.showModal()
|
||||||
|
document.body.classList.add('overflow-hidden')
|
||||||
|
this.element.addEventListener("close", this.enableBodyScroll.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.element.removeEventListener("close", this.enableBodyScroll.bind(this))
|
||||||
|
this.element.close()
|
||||||
|
// clean up modal content
|
||||||
|
const frame = document.getElementById('modal')
|
||||||
|
frame.removeAttribute("src")
|
||||||
|
frame.innerHTML = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
enableBodyScroll() {
|
||||||
|
document.body.classList.remove('overflow-hidden')
|
||||||
|
}
|
||||||
|
|
||||||
|
clickOutside(event) {
|
||||||
|
console.log("clickOutside", event.target, this)
|
||||||
|
if (event.target === this.element) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
16
app/javascript/controllers/dropdown_menu_controller.js
Normal file
16
app/javascript/controllers/dropdown_menu_controller.js
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
// Connects to data-controller="dropdown-menu"
|
||||||
|
export default class extends Controller {
|
||||||
|
connect() {
|
||||||
|
const x = this.element
|
||||||
|
this.element.addEventListener("turbo:click", e => {
|
||||||
|
console.log("turbo visit dropdown", e, this.element)
|
||||||
|
this.element.removeAttribute("open");
|
||||||
|
})
|
||||||
|
this.element.addEventListener("turbo:submit-start", e => {
|
||||||
|
console.log("turbo submit dropdown", e, this.element)
|
||||||
|
this.element.removeAttribute("open");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
import { application } from "./application"
|
import { application } from "./application"
|
||||||
|
|
||||||
|
import Lightbox from '@stimulus-components/lightbox'
|
||||||
|
application.register('lightbox', Lightbox)
|
||||||
|
|
||||||
import AutosubmitController from "./autosubmit_controller"
|
import AutosubmitController from "./autosubmit_controller"
|
||||||
application.register("autosubmit", AutosubmitController)
|
application.register("autosubmit", AutosubmitController)
|
||||||
|
|
||||||
|
|
@ -19,9 +22,15 @@ application.register("collapse-chevron-toggler", CollapseChevronTogglerControlle
|
||||||
import DetailsListController from "./details_list_controller"
|
import DetailsListController from "./details_list_controller"
|
||||||
application.register("details-list", DetailsListController)
|
application.register("details-list", DetailsListController)
|
||||||
|
|
||||||
|
import DialogController from "./dialog_controller"
|
||||||
|
application.register("dialog", DialogController)
|
||||||
|
|
||||||
import DragController from "./drag_controller"
|
import DragController from "./drag_controller"
|
||||||
application.register("drag", DragController)
|
application.register("drag", DragController)
|
||||||
|
|
||||||
|
import DropdownMenuController from "./dropdown_menu_controller"
|
||||||
|
application.register("dropdown-menu", DropdownMenuController)
|
||||||
|
|
||||||
import HelloController from "./hello_controller"
|
import HelloController from "./hello_controller"
|
||||||
application.register("hello", HelloController)
|
application.register("hello", HelloController)
|
||||||
|
|
||||||
|
|
@ -43,5 +52,8 @@ application.register("sortable", SortableController)
|
||||||
import ThemeSwitcherController from "./theme_switcher_controller"
|
import ThemeSwitcherController from "./theme_switcher_controller"
|
||||||
application.register("theme-switcher", ThemeSwitcherController)
|
application.register("theme-switcher", ThemeSwitcherController)
|
||||||
|
|
||||||
|
import ToastController from "./toast_controller"
|
||||||
|
application.register("toast", ToastController)
|
||||||
|
|
||||||
import UnsavedChangesController from "./unsaved_changes_controller"
|
import UnsavedChangesController from "./unsaved_changes_controller"
|
||||||
application.register("unsaved-changes", UnsavedChangesController)
|
application.register("unsaved-changes", UnsavedChangesController)
|
||||||
|
|
|
||||||
14
app/javascript/controllers/toast_controller.js
Normal file
14
app/javascript/controllers/toast_controller.js
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
import * as bootstrap from "bootstrap"
|
||||||
|
|
||||||
|
// Connects to data-controller="toast"
|
||||||
|
export default class extends Controller {
|
||||||
|
connect() {
|
||||||
|
const shownKey = `toastsShown[${this.element.getAttribute("data-ts")}]`
|
||||||
|
if(!window.sessionStorage.getItem(shownKey)) {
|
||||||
|
window.sessionStorage.setItem(shownKey, Date.now());
|
||||||
|
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(this.element)
|
||||||
|
toastBootstrap.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Check < ApplicationRecord
|
class Check < ApplicationRecord
|
||||||
belongs_to :principle
|
belongs_to :guideline
|
||||||
|
|
||||||
has_and_belongs_to_many :links
|
has_and_belongs_to_many :links
|
||||||
has_and_belongs_to_many :standards
|
has_and_belongs_to_many :standards
|
||||||
|
|
@ -51,9 +51,9 @@ class Check < ApplicationRecord
|
||||||
:standard_text,
|
:standard_text,
|
||||||
:powerpoint_text
|
:powerpoint_text
|
||||||
|
|
||||||
validates :number, uniqueness: true, presence: true
|
validates :number, uniqueness: { scope: :guideline_id }, presence: true
|
||||||
|
|
||||||
before_validation { self.number = self.class.maximum(:id).to_i + 1 unless self.number.present? }
|
# before_validation { self.number = self.class.maximum(:id).to_i + 1 unless self.number.present? }
|
||||||
|
|
||||||
scope(:search, lambda { |terms|
|
scope(:search, lambda { |terms|
|
||||||
# TODO: Search only fields for current locale.
|
# TODO: Search only fields for current locale.
|
||||||
|
|
@ -129,4 +129,20 @@ class Check < ApplicationRecord
|
||||||
def external_number
|
def external_number
|
||||||
[ external_number_1, external_number_2, external_number_3 ].compact_blank.join(".")
|
[ external_number_1, external_number_2, external_number_3 ].compact_blank.join(".")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def external_number
|
||||||
|
[
|
||||||
|
guideline.principle.id,
|
||||||
|
guideline.number,
|
||||||
|
number
|
||||||
|
].compact.join(".")
|
||||||
|
end
|
||||||
|
|
||||||
|
def full_number
|
||||||
|
external_number
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
display_label
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,12 @@ class Element < ApplicationRecord
|
||||||
before_validation :set_position
|
before_validation :set_position
|
||||||
before_update :update_positions, if: :position_changed?
|
before_update :update_positions, if: :position_changed?
|
||||||
|
|
||||||
|
has_one_attached :screenshot do |attachable|
|
||||||
|
attachable.variant :thumbnail, resize_to_limit: [ 200, 200 ]
|
||||||
|
end
|
||||||
|
|
||||||
|
scope :failed, -> { where(SuccessCriterion.where(result: SuccessCriterion.results[:failed]).arel.exists) }
|
||||||
|
|
||||||
# Calculate actual conformity level:
|
# Calculate actual conformity level:
|
||||||
# - if a success_criterion has result :failed -> the confirmity_level
|
# - if a success_criterion has result :failed -> the confirmity_level
|
||||||
# of that success_criterion is not reached.
|
# of that success_criterion is not reached.
|
||||||
|
|
|
||||||
18
app/models/guideline.rb
Normal file
18
app/models/guideline.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
class Guideline < ApplicationRecord
|
||||||
|
belongs_to :principle
|
||||||
|
|
||||||
|
has_many :checks
|
||||||
|
|
||||||
|
has_rich_text :description_de
|
||||||
|
has_rich_text :description_en
|
||||||
|
|
||||||
|
translates_attributes :name, :description
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{full_number} #{t_name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def full_number
|
||||||
|
[ principle.id, number ].join(".")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
module PdfDocuments
|
module PdfDocuments
|
||||||
class Base
|
class Base
|
||||||
attr_reader :params
|
attr_reader :params, :font
|
||||||
|
|
||||||
def initialize(prawn_document, **params)
|
def initialize(prawn_document, **params)
|
||||||
@prawn_document = prawn_document
|
@prawn_document = prawn_document
|
||||||
|
|
@ -13,7 +13,8 @@ module PdfDocuments
|
||||||
# exta_bold: 'vendor/assets/fonts/Lexend-ExtraBold.ttf',
|
# exta_bold: 'vendor/assets/fonts/Lexend-ExtraBold.ttf',
|
||||||
# italic: 'vendor/assets/fonts/Lexend-Regular.ttf'
|
# italic: 'vendor/assets/fonts/Lexend-Regular.ttf'
|
||||||
# })
|
# })
|
||||||
@prawn_document.font "Helvetica", size: 12
|
@font = "Helvetica"
|
||||||
|
@prawn_document.font @font, size: 12
|
||||||
@params = OpenStruct.new(params)
|
@params = OpenStruct.new(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -40,8 +41,12 @@ module PdfDocuments
|
||||||
@prawn_document.markup "<h3>#{text}</h3>"
|
@prawn_document.markup "<h3>#{text}</h3>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def text(text)
|
def heading4(text)
|
||||||
@prawn_document.text text, markup_options[:text]
|
@prawn_document.markup "<h4>#{text}</h4>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def text(text, **args)
|
||||||
|
@prawn_document.text text, markup_options[:text].merge(args)
|
||||||
end
|
end
|
||||||
|
|
||||||
def rich_text(text)
|
def rich_text(text)
|
||||||
|
|
@ -55,28 +60,28 @@ module PdfDocuments
|
||||||
def markup_options
|
def markup_options
|
||||||
{
|
{
|
||||||
text: { size: 12, margin_bottom: 5 },
|
text: { size: 12, margin_bottom: 5 },
|
||||||
heading1: { style: :bold, size: 26, margin_bottom: 10, margin_top: 0 },
|
heading1: { style: :bold, size: 26, margin_bottom: 5, margin_top: 0 },
|
||||||
heading2: { style: :bold, size: 17, margin_bottom: 10, margin_top: 5 },
|
heading2: { style: :bold, size: 17, margin_bottom: 5, margin_top: 5 },
|
||||||
heading3: { style: :bold, size: 13, margin_bottom: 10, margin_top: 5 },
|
heading3: { style: :bold, size: 13, margin_bottom: 5, margin_top: 5 },
|
||||||
heading4: { style: :bold, size: 12, margin_bottom: 10, margin_top: 5 },
|
heading4: { style: :bold, size: 12, margin_bottom: 5, margin_top: 5 },
|
||||||
heading5: { style: :bold, size: 12, margin_bottom: 10, margin_top: 5 },
|
heading5: { style: :bold, size: 12, margin_bottom: 5, margin_top: 5 },
|
||||||
heading6: { style: :thin, size: 12, margin_bottom: 10, margin_top: 5 }
|
heading6: { style: :thin, size: 12, margin_bottom: 5, margin_top: 5 }
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def logo
|
def logo(width: 24, xs: true)
|
||||||
@prawn_document.image "app/assets/images/logo-apfelschule.png", width: 150
|
@prawn_document.image "app/assets/images/logo-apfelschule#{ xs ? "_xs" : "" }.png", width:
|
||||||
@prawn_document.move_down 30
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare_rich_text(rich_text)
|
def prepare_rich_text(rich_text)
|
||||||
{ h1: "h4" }.each do |tag, replacement|
|
{ h1: "h5" }.each do |tag, replacement|
|
||||||
rich_text = rich_text.to_s.gsub("<#{tag}", "<#{replacement}")
|
rich_text = rich_text.to_s.gsub("<#{tag}", "<#{replacement}")
|
||||||
rich_text = rich_text.to_s.gsub("</#{tag}>", "</#{replacement}>")
|
rich_text = rich_text.to_s.gsub("</#{tag}>", "</#{replacement}>")
|
||||||
end
|
end
|
||||||
|
|
||||||
rich_text
|
rich_text.sub(/(<br>)+$/, "")
|
||||||
end
|
end
|
||||||
|
# @prawn_document.draw_text("Dokument erstellt am #{Time.current.strftime('%d %B %Y')} um #{Time.current.strftime('%H:%M:%S')}", at: [ 0, -15 ])
|
||||||
|
|
||||||
def font(...)
|
def font(...)
|
||||||
@prawn_document.font(...)
|
@prawn_document.font(...)
|
||||||
|
|
@ -89,5 +94,58 @@ module PdfDocuments
|
||||||
def move_down(...)
|
def move_down(...)
|
||||||
@prawn_document.move_down(...)
|
@prawn_document.move_down(...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def safe_display(value, &block)
|
||||||
|
return if value.blank?
|
||||||
|
|
||||||
|
begin
|
||||||
|
yield(value)
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def bold(text)
|
||||||
|
@prawn_document.font(@font, style: :bold) do
|
||||||
|
@prawn_document.text text
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def image(attachable, **args)
|
||||||
|
begin
|
||||||
|
@prawn_document.image(ActiveStorage::Blob.service.path_for(attachable.key), **args) && raise("david")
|
||||||
|
rescue StandardError
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def without_page_break(&block)
|
||||||
|
return yield
|
||||||
|
return @prawn_document.bounding_box([ 0, @prawn_document.cursor ], width: 300) do
|
||||||
|
yield
|
||||||
|
# @prawn_document.stroke_bounds if Rails.env.development?
|
||||||
|
# print_coordinates
|
||||||
|
end
|
||||||
|
@prawn_document.span(520) do
|
||||||
|
yield
|
||||||
|
# @prawn_document.stroke_bounds
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def print_coordinates
|
||||||
|
@prawn_document.text("top: #{@prawn_document.bounds.top}")
|
||||||
|
@prawn_document.text("bottom: #{@prawn_document.bounds.bottom}")
|
||||||
|
@prawn_document.text("left: #{@prawn_document.bounds.left}")
|
||||||
|
@prawn_document.text("right: #{@prawn_document.bounds.right}")
|
||||||
|
@prawn_document.move_down(10)
|
||||||
|
@prawn_document.text("absolute top: #{Float(@prawn_document.bounds.absolute_top).round(2)}")
|
||||||
|
@prawn_document.text("absolute bottom: #{Float(@prawn_document.bounds.absolute_bottom).round(2)}")
|
||||||
|
@prawn_document.text("absolute left: #{Float(@prawn_document.bounds.absolute_left).round(2)}")
|
||||||
|
@prawn_document.text("absolute right: #{Float(@prawn_document.bounds.absolute_right).round(2)}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_page(required_space: 0)
|
||||||
|
@prawn_document.start_new_page if @prawn_document.cursor <= required_space + 10
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,26 +5,163 @@ module PdfDocuments
|
||||||
private
|
private
|
||||||
|
|
||||||
def generate
|
def generate
|
||||||
logo
|
move_down 130
|
||||||
@prawn_document.formatted_text_box [ {
|
logo(width: 250, xs: false)
|
||||||
text: "Dieses Dokument wurd am #{Time.current.strftime('%d %B %Y')} um #{Time.current.strftime('%H:%M:%S')} erstellt.", size: 8, align: :right
|
move_down 40
|
||||||
} ], align: :right
|
|
||||||
|
|
||||||
heading1 params.report.name
|
heading1 params.report.name
|
||||||
rich_text params.report.comment
|
|
||||||
|
|
||||||
params.report.elements.each.with_index(1) do |element, element_index|
|
move_down 20
|
||||||
heading2 "#{element_index} #{element.title}"
|
@prawn_document.text "#{I18n.l params.report.updated_at.to_date, format: :long}"
|
||||||
formatted_text [ { text: element.path, styles: %i[bold italic underline] } ]
|
move_down 40
|
||||||
move_down(5)
|
safe_display(params.report.comment) do
|
||||||
rich_text element.description_html
|
rich_text _1
|
||||||
|
move_down 30
|
||||||
|
end
|
||||||
|
|
||||||
element.success_criteria.each.with_index(1) do |success_criterion, sc_index|
|
@prawn_document.font_size(8) do
|
||||||
heading3 "#{element_index}.#{sc_index} #{success_criterion.title}"
|
@prawn_document.draw_text("Dokument erstellt am #{Time.current.strftime('%d %B %Y')} um #{Time.current.strftime('%H:%M:%S')}", at: [ 0, 0 ])
|
||||||
rich_text success_criterion.description_html
|
end
|
||||||
rich_text success_criterion.comment
|
@prawn_document.start_new_page
|
||||||
|
@pages = {}
|
||||||
|
|
||||||
|
params.report.export[:elements].each.with_index(1) do |(element, success_criteria), element_index|
|
||||||
|
new_page(required_space: 200) if element_index > 1
|
||||||
|
without_page_break do
|
||||||
|
heading2 "#{element_index} #{element.title}"
|
||||||
|
@prawn_document.text("<b>Pfad:</b> #{element.page.path}", inline_format: true)
|
||||||
|
safe_display(element.screenshot) do
|
||||||
|
image(_1.variant(:thumbnail), height: 160)
|
||||||
|
move_down(15)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rich_text element.description
|
||||||
|
move_down(10)
|
||||||
|
|
||||||
|
success_criteria.each.with_index(1) do |success_criterion, sc_index|
|
||||||
|
@pages[success_criterion] = @prawn_document.page_number
|
||||||
|
success_criterion_row(success_criterion, [ element_index, sc_index ])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@prawn_document.start_new_page
|
||||||
|
heading1("Anhang: Richtlinien")
|
||||||
|
params.report.export[:success_criteria].group_by(&:check).sort_by { |c, _scs| c.external_number }.each do |check, criteria|
|
||||||
|
heading2(check.display_label)
|
||||||
|
@pages[check] = @prawn_document.page_number
|
||||||
|
{
|
||||||
|
external_number: { label: "WCAG Nummer" },
|
||||||
|
external_url: { label: "WCAG Link" },
|
||||||
|
conformity_level: { label: "Konformität" },
|
||||||
|
conformity_notice_de: { label: "Anmerkung Konformität", rich: true },
|
||||||
|
priority: { label: "Priorität" },
|
||||||
|
criterion_de: { label: "Kriterium/Grundlage", rich: true },
|
||||||
|
exemption_details_de: { label: "Ausnahmen", rich: true },
|
||||||
|
criterion_details_de: { label: "Verstehen", rich: true },
|
||||||
|
example_de: { label: "Beispiel", rich: true },
|
||||||
|
annotation_de: { label: "Anmerkung", rich: true }
|
||||||
|
}.each do |attribute, options|
|
||||||
|
v = check.send(attribute)
|
||||||
|
safe_display(v) do
|
||||||
|
text("<b>#{options[:label]}</b>", inline_format: true)
|
||||||
|
if options[:rich]
|
||||||
|
rich_text(_1)
|
||||||
|
else
|
||||||
|
text(_1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if check.links.any?
|
||||||
|
move_down 5
|
||||||
|
text("<b>Links</b>", inline_format: true)
|
||||||
|
move_down 5
|
||||||
|
check.links.group_by(&:link_category).each do |cat, links|
|
||||||
|
rich_text(%Q(
|
||||||
|
<span>#{cat.name}</span>
|
||||||
|
<ul>
|
||||||
|
#{links.map { "<li><a href='#{_1.url}'>#{_1.text}</a></li>" }.join() }
|
||||||
|
</ul>
|
||||||
|
))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
text("<b>Erfolgskriterien</b>", inline_format: true)
|
||||||
|
text criteria.map(&:number).sort.join(", ")
|
||||||
|
end
|
||||||
|
string = "Seite <page> / <total>"
|
||||||
|
# Green page numbers 1 to 7
|
||||||
|
options = {
|
||||||
|
at: [ @prawn_document.bounds.right - 150, 776 ],
|
||||||
|
width: 150,
|
||||||
|
align: :right,
|
||||||
|
start_count_at: 2,
|
||||||
|
page_filter: ->(x) { x > 1 }
|
||||||
|
}
|
||||||
|
@prawn_document.number_pages string, options
|
||||||
|
|
||||||
|
@prawn_document.repeat(2..) do
|
||||||
|
@prawn_document.text_box "<b>#{params.report.name}</b>", at: [ 50, 777 ], inline_format: true, width: 300
|
||||||
|
@prawn_document.bounding_box([ 0, 766 ], width: 532) do
|
||||||
|
hr
|
||||||
|
end
|
||||||
|
@prawn_document.bounding_box([ 0, 796 ], width: 200, height: 200) do
|
||||||
|
logo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
x = params
|
||||||
|
p = @pages
|
||||||
|
@prawn_document.outline.define do
|
||||||
|
x.report.export[:elements].each.with_index(1) do |(element, success_criteria), element_index|
|
||||||
|
section("#{element_index} #{element.title}") do
|
||||||
|
success_criteria.each.with_index(1) do |sc, sc_index|
|
||||||
|
page(title: "#{element_index}.#{sc_index} #{sc.title}", destination: p[sc])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
section("Anhang: Richtlinien") do
|
||||||
|
x.report.export[:success_criteria].group_by(&:check).sort_by { |c, _scs| c.external_number }.each do |check, _criteria|
|
||||||
|
page(title: check.display_label, destination: p[check])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def success_criterion_row(success_criterion, index)
|
||||||
|
heading3 "#{index.join(".")} #{success_criterion.title}"
|
||||||
|
safe_display(success_criterion.test_comment) do
|
||||||
|
without_page_break do
|
||||||
|
heading4 "Kommentar"
|
||||||
|
rich_text success_criterion.test_comment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
safe_display(success_criterion.quick_criterion) do
|
||||||
|
without_page_break do
|
||||||
|
heading4 "Kriterium"
|
||||||
|
rich_text success_criterion.quick_criterion
|
||||||
|
end
|
||||||
|
end
|
||||||
|
safe_display(success_criterion.quick_fail) do
|
||||||
|
without_page_break do
|
||||||
|
heading4 "Fail"
|
||||||
|
rich_text success_criterion.quick_fail
|
||||||
|
end
|
||||||
|
end
|
||||||
|
safe_display(success_criterion.quick_fix) do
|
||||||
|
without_page_break do
|
||||||
|
heading4 "Fix"
|
||||||
|
rich_text success_criterion.quick_fix
|
||||||
|
end
|
||||||
|
end
|
||||||
|
heading4("Protokollnummer")
|
||||||
|
text(success_criterion.number)
|
||||||
|
safe_display(success_criterion.check.external_url) do
|
||||||
|
heading4("WCAG")
|
||||||
|
text("<link href='#{_1}'>#{success_criterion.check.external_number || _1}</link>", inline_format: true)
|
||||||
|
end
|
||||||
|
move_down(10)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
7
app/models/project.rb
Normal file
7
app/models/project.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
class Project < ApplicationRecord
|
||||||
|
has_many :reports, dependent: :restrict_with_error
|
||||||
|
|
||||||
|
has_rich_text :details
|
||||||
|
|
||||||
|
scope :current, -> { where("updated_at > ?", 1.month.ago) }
|
||||||
|
end
|
||||||
|
|
@ -1,9 +1,28 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Report < ApplicationRecord
|
class Report < ApplicationRecord
|
||||||
|
belongs_to :project, touch: true
|
||||||
|
|
||||||
has_many :pages, -> { order(:position) }, dependent: :destroy
|
has_many :pages, -> { order(:position) }, dependent: :destroy
|
||||||
has_many :elements, through: :pages, dependent: :destroy
|
has_many :elements, through: :pages, dependent: :destroy
|
||||||
|
has_many :success_criteria, through: :elements, dependent: :destroy
|
||||||
|
|
||||||
has_rich_text :comment
|
has_rich_text :comment
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
|
def export
|
||||||
|
export_success_criteria = success_criteria.failed
|
||||||
|
export_elements = export_success_criteria.group_by(&:element)
|
||||||
|
export_pages = export_elements.group_by { |k, v| k }
|
||||||
|
{
|
||||||
|
pages: export_pages,
|
||||||
|
elements: export_elements,
|
||||||
|
success_criteria: export_success_criteria
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test
|
||||||
|
139
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ class SuccessCriterion < ApplicationRecord
|
||||||
before_save :set_position
|
before_save :set_position
|
||||||
before_update :update_positions, if: :position_changed?
|
before_update :update_positions, if: :position_changed?
|
||||||
|
|
||||||
|
validates :result, inclusion: { in: self.results.keys + [ nil ] }
|
||||||
|
|
||||||
|
scope :failed, -> { where(result: :failed) }
|
||||||
|
|
||||||
def level_value
|
def level_value
|
||||||
return nil unless level
|
return nil unless level
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@
|
||||||
<%= link_to Checklist.model_name.human(count: Checklist.count), :checklists %>
|
<%= link_to Checklist.model_name.human(count: Checklist.count), :checklists %>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<i class="bi bi-rulers"></i>
|
||||||
|
<%= Guideline.count %>
|
||||||
|
<%= link_to Guideline.model_name.human(count: Guideline.count), :guidelines %>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<i class="bi bi-check2"></i>
|
<i class="bi bi-check2"></i>
|
||||||
<%= Check.count %>
|
<%= Check.count %>
|
||||||
|
|
@ -27,4 +33,4 @@
|
||||||
<li>
|
<li>
|
||||||
<%= link_to "ZIP Backup herunterladen", admin_backup_url(format: :zip), class: " ", data: { turbo_prefetch: false, frame: "_top", turbo: false } %>
|
<%= link_to "ZIP Backup herunterladen", admin_backup_url(format: :zip), class: " ", data: { turbo_prefetch: false, frame: "_top", turbo: false } %>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
<%= turbo_stream.remove dom_id(@checklist_entry) %>
|
<%= turbo_stream.remove dom_id(@checklist_entry) %>
|
||||||
|
<%= turbo_stream_toast("Check wurde aus Checkliste entfernt", true) %>
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ div id=dom_id(check)
|
||||||
th = Check.human_attribute_name(:number)
|
th = Check.human_attribute_name(:number)
|
||||||
td = check.number
|
td = check.number
|
||||||
tr
|
tr
|
||||||
th = Principle.model_name.human
|
th = Guideline.model_name.human
|
||||||
td = check.principle&.t_name
|
td = check.guideline&.name_en
|
||||||
tr
|
tr
|
||||||
th = Standard.model_name.human(count: check.standard_ids.size)
|
th = Standard.model_name.human(count: check.standard_ids.size)
|
||||||
td = check.standards.map(&:t_name).sort_by(&:downcase).join(", ")
|
td = check.standards.map(&:t_name).sort_by(&:downcase).join(", ")
|
||||||
|
|
@ -80,4 +80,4 @@ div id=dom_id(check)
|
||||||
ul
|
ul
|
||||||
- check.links.select{ _1.link_category == category }.map { |link| link_to link.text, link.url, target: :_blank }.each do |link|
|
- check.links.select{ _1.link_category == category }.map { |link| link_to link.text, link.url, target: :_blank }.each do |link|
|
||||||
li = link
|
li = link
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
= bootstrap_form_with(model: check, remote: true, data: { controller: "unsaved-changes" }) do |form|
|
= bootstrap_form_with(model: check, remote: true, data: { controller: "unsaved-changes" }) do |form|
|
||||||
h2 Details
|
h2 Details
|
||||||
= multilang_form_field(form, :name)
|
= multilang_form_field(form, :name)
|
||||||
= form.text_field :number, required: false
|
|
||||||
.row
|
.row
|
||||||
= form.collection_radio_buttons(:principle_id, Principle.all.sort_by(&:t_name), :id, :t_name) { |b| b.label(class: "col-md-2") { b.radio_button + b.text } }
|
= form.collection_radio_buttons(:guideline_id, Guideline.all.sort_by(&:full_number), :id, :to_s) { |b| b.label(class: "col-md-2") { b.radio_button + b.text } }
|
||||||
|
= form.text_field :number, required: false
|
||||||
= form.collection_check_boxes :standard_ids, Standard.all.sort_by{ _1.t_name.downcase }, :id, :t_name, include_blank: true
|
= form.collection_check_boxes :standard_ids, Standard.all.sort_by{ _1.t_name.downcase }, :id, :t_name, include_blank: true
|
||||||
|
|
||||||
h2 Einschränkung/Zugänglichkeit
|
h2 Einschränkung/Zugänglichkeit
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<div id="<%= dom_id element %>" class="mb-5">
|
<div id="<%= dom_id element %>" class="mb-5">
|
||||||
<%= turbo_frame_tag dom_id(element, :frame) do %>
|
<%= turbo_frame_tag dom_id(element, :frame) do %>
|
||||||
<div class="d-flex">
|
<div class="d-flex border-bottom mb-3">
|
||||||
<h3 class="h4">
|
<h3 class="h4">
|
||||||
<i class="bi bi-boxes">
|
<i class="bi bi-boxes">
|
||||||
</i>
|
</i>
|
||||||
|
|
@ -9,22 +9,23 @@
|
||||||
<%= element.title %>
|
<%= element.title %>
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
<%= link_to [:edit, element], class: "btn btn-link text-secondary" do %>
|
<%= element_menu(element) %>
|
||||||
<i class="bi bi-pencil">
|
</div>
|
||||||
</i>
|
|
||||||
|
<div class="d-flex flex-column flex-sm-row">
|
||||||
|
<% if element.description %>
|
||||||
|
<div class="mb-3 flex-fill">
|
||||||
|
<%= element.description %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= button_to(element_path(element), method: :delete, class: "btn btn-link text-danger", data: { turbo_confirm: "Bist du sicher?"}) do %>
|
<% safe_display(element.screenshot) do |s| %>
|
||||||
<i class="bi bi-trash"></i>
|
<div class="mb-3" data-controller="lightbox">
|
||||||
|
<%= link_to(s) do %>
|
||||||
|
<%= image_tag(s.variant(:thumbnail), class: "img-fluid", alt: "Screenshot des getesteten Elements") %>
|
||||||
|
<% end rescue nil %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% if element.description %>
|
|
||||||
<div class="mb-3">
|
|
||||||
<%= element.description %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<p class="actions">
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div id="<%= dom_id(element, :success_criteria_list) %>" class="mb-3" data-controller="sortable" data-form-name="success_criterion" data-position-attribute= "position" data-draggable-selector=".draggable">
|
<div id="<%= dom_id(element, :success_criteria_list) %>" class="mb-3" data-controller="sortable" data-form-name="success_criterion" data-position-attribute= "position" data-draggable-selector=".draggable">
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
</div>
|
</div>
|
||||||
<%= element.description_html %>
|
<%= element.description_html %>
|
||||||
|
|
||||||
|
<%= image_tag(element.screenshot.preview(:thumbnail)) %>
|
||||||
|
<%= image_tag(element.screenshot) %>
|
||||||
|
|
||||||
<% element.success_criteria.each do |sc| %>
|
<% element.success_criteria.each do |sc| %>
|
||||||
<%= render sc %>
|
<%= render sc %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<%= bootstrap_form_with(model: element.persisted? ? element : [:page, element], class: "mb-3") do |form| %>
|
|
||||||
<%= form.hidden_field :page_id %>
|
|
||||||
<%= form.text_field :title %>
|
|
||||||
<%= form.rich_text_area :description %>
|
|
||||||
<%= form.submit class: "btn btn-primary" %>
|
|
||||||
<%= link_to("Abbrechen", element.persisted? ? element : element.report, class: "btn btn-outline-secondary") %>
|
|
||||||
<% end %>
|
|
||||||
10
app/views/elements/_form.html.slim
Normal file
10
app/views/elements/_form.html.slim
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
= bootstrap_form_with(model: element.persisted? ? element : [:page, element], class: "mb-3") do |form|
|
||||||
|
= form.hidden_field :page_id
|
||||||
|
= form.text_field :title
|
||||||
|
= form.rich_text_area :description
|
||||||
|
= form.file_field :screenshot
|
||||||
|
- if element.persisted?
|
||||||
|
= safe_display(element.screenshot) { tag.div(link_to(_1.filename.to_s, _1), class: "mb-3") }
|
||||||
|
= form.submit class: "btn btn-primary"
|
||||||
|
- unless modal?
|
||||||
|
= link_to("Abbrechen", element.persisted? ? element : element.report, class: "btn btn-outline-secondary")
|
||||||
|
|
@ -1,13 +1,7 @@
|
||||||
li id=dom_id(element, :page_nav_row) data={ "sortable-url": element_path(element), "form-name": "element", "position-attribute": "position" }
|
li.d-flex id=dom_id(element, :page_nav_row) data={ "sortable-url": element_path(element), "form-name": "element", "position-attribute": "position" }
|
||||||
- if current_page
|
- url = current_page ? "##{dom_id(element)}" : report_path(element.report, page_id: element.page.id, anchor: dom_id(element))
|
||||||
=< link_to("##{dom_id(element)}", data: { "turbo": false }) do
|
i.bi.bi-boxes.me-2
|
||||||
i.bi.bi-boxes.me-2
|
=< link_to(url, data: { "turbo": false }, class: "me-auto") do
|
||||||
span id=dom_id(element, :page_nav_title)
|
span id=dom_id(element, :page_nav_title)
|
||||||
= "#{element.number} #{element.title}"
|
= "#{element.number} #{element.title}"
|
||||||
i.bi.bi-grip-vertical.float-end.handle
|
i.bi.bi-grip-vertical.handle
|
||||||
- else
|
|
||||||
=< link_to(report_path(element.report, page_id: element.page.id, anchor: dom_id(element)), data: { "turbo": false }) do
|
|
||||||
i.bi.bi-boxes.me-2
|
|
||||||
span id=dom_id(element, :page_nav_title)
|
|
||||||
=< "#{element.number} #{element.title}"
|
|
||||||
i.bi.bi-grip-vertical.float-end.handle
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
= turbo_stream.update "new_element_frame", partial: "pages/new_element_button", locals: { page: @element.page }
|
= turbo_stream.update "new_element_frame", partial: "pages/new_element_button", locals: { page: @element.page }
|
||||||
= turbo_stream.append "element_list", @element
|
= turbo_stream.append "element_list", @element
|
||||||
= turbo_stream.append dom_id(@element.page, :page_nav_elements), partial: "elements/page_nav_row", locals: { element: @element, current_page: true }
|
= turbo_stream.append dom_id(@element.page, :page_nav_elements), partial: "elements/page_nav_row", locals: { element: @element, current_page: true }
|
||||||
|
|
||||||
|
|
||||||
|
= turbo_stream_toast("Element hinzugefügt", false)
|
||||||
|
|
@ -2,4 +2,7 @@
|
||||||
= turbo_stream.remove dom_id(@element, :page_nav_row)
|
= turbo_stream.remove dom_id(@element, :page_nav_row)
|
||||||
- @element.page.elements.reject { _1 == @element }.each do |e|
|
- @element.page.elements.reject { _1 == @element }.each do |e|
|
||||||
= turbo_stream.update dom_id(e, :title), "#{e.page.position}.#{e.position} #{e.title}"
|
= turbo_stream.update dom_id(e, :title), "#{e.page.position}.#{e.position} #{e.title}"
|
||||||
= turbo_stream.replace dom_id(e, :page_nav_row), partial: "elements/page_nav_row", locals: { element: e, current_page: true }
|
= turbo_stream.replace dom_id(e, :page_nav_row), partial: "elements/page_nav_row", locals: { element: e, current_page: true }
|
||||||
|
|
||||||
|
|
||||||
|
= turbo_stream_toast("Element wurde gelöscht", true)
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,17 @@
|
||||||
<h1><%= t("scaffold.pagetitle_edit", model: Element.model_name.human) %></h1>
|
<h1><%= t("scaffold.pagetitle_edit", model: Element.model_name.human) %></h1>
|
||||||
|
|
||||||
<%= turbo_frame_tag dom_id(@element, :frame) do %>
|
|
||||||
<div>
|
<div>
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<h2 class="h3">
|
<h2 class="h3">
|
||||||
<i class="bi bi-boxes">
|
<i class="bi bi-boxes">
|
||||||
</i>
|
</i>
|
||||||
<%= @element.title %>
|
<%= @element.title %>
|
||||||
<%= link_to(tag.i(class: "bi bi-pencil"), @element, class: "btn btn-link text-warning") %>
|
|
||||||
</div>
|
</div>
|
||||||
<%= render "form", element: @element %>
|
<%= render "form", element: @element %>
|
||||||
</div>
|
</div>
|
||||||
|
<% unless modal? %>
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_show", model: Element.model_name.human), @element %>
|
||||||
|
<%= link_to t("scaffold.link_index", model: Element.model_name.human(count: 2)), page_elements_path(@element.page) %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="action-row">
|
|
||||||
<%= link_to t("scaffold.link_show", model: Element.model_name.human), @element %>
|
|
||||||
<%= link_to t("scaffold.link_index", model: Element.model_name.human(count: 2)), page_elements_path(@element.page) %>
|
|
||||||
</div>
|
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,8 @@
|
||||||
/ - element.success_criteria.each do |sc|
|
/ - element.success_criteria.each do |sc|
|
||||||
/ = turbo_stream.update dom_id(sc, :title), "#{sc.page.position}.#{sc.element.position}.#{sc.position} #{sc.title}"
|
/ = turbo_stream.update dom_id(sc, :title), "#{sc.page.position}.#{sc.element.position}.#{sc.position} #{sc.title}"
|
||||||
- element.success_criteria.each do |sc|
|
- element.success_criteria.each do |sc|
|
||||||
= turbo_stream.update dom_id(sc, :position), "#{sc.page.position}.#{sc.element.position}.#{sc.position}"
|
= turbo_stream.update dom_id(sc, :position), "#{sc.page.position}.#{sc.element.position}.#{sc.position}"
|
||||||
|
= turbo_stream.replace dom_id(element, :frame), element
|
||||||
|
|
||||||
|
|
||||||
|
= turbo_stream_toast("Element gespeichert", false)
|
||||||
|
|
@ -1,55 +1,99 @@
|
||||||
h1 id=dom_id(@report) = @report.name
|
h1.title id=dom_id(@report) = @report.name
|
||||||
|
|
||||||
h2#toc Inhaltsverzeichnis
|
h2 1 Einschätzung
|
||||||
nav
|
p Gibt es hier Text?
|
||||||
= link_to(@report.name, "##{dom_id(@report)}")
|
|
||||||
ul
|
|
||||||
li = link_to("Inhaltsverzeichnis", "#toc")
|
|
||||||
li
|
|
||||||
= link_to('Testbericht')
|
|
||||||
ul
|
|
||||||
- @report.pages.select { |p| p.elements.any? { |e| e.success_criteria.any?(&:failed?) } }.each do |page|
|
|
||||||
li
|
|
||||||
= link_to("#{page.position} #{page.path}", "##{dom_id(page)}")
|
|
||||||
ul
|
|
||||||
- page.elements.select { |e| e.success_criteria.any?(&:failed?) }.each do |element|
|
|
||||||
li
|
|
||||||
= link_to("#{element.number} #{element.title}")
|
|
||||||
ul
|
|
||||||
- element.success_criteria.select(&:failed?).each do |sc|
|
|
||||||
li = link_to("#{sc.number} #{sc.title}", "##{dom_id(sc)}")
|
|
||||||
li
|
|
||||||
= link_to("Anhang")
|
|
||||||
ul
|
|
||||||
- @failed_success_criteria.group_by(&:check).each do |check, scs|
|
|
||||||
li = link_to(check.display_label)
|
|
||||||
|
|
||||||
|
h3 1.1 Zielsetzung und Ausgangslage
|
||||||
|
p Woher kommt dieser Text?
|
||||||
|
|
||||||
h2 Testbericht
|
h3 1.2 Wie wurde getestet
|
||||||
|
p Woher kommt dieser Text?
|
||||||
|
|
||||||
|
h3 1.3 Einschätzung
|
||||||
|
p Woher kommt dieser Text?
|
||||||
|
|
||||||
|
h2 2 Protokoll
|
||||||
|
- current_page_pos = 0
|
||||||
|
- current_abs_element_pos = 0
|
||||||
- @report.pages.select { |p| p.elements.any? { |e| e.success_criteria.any? { _1.failed? } } }.each do |page|
|
- @report.pages.select { |p| p.elements.any? { |e| e.success_criteria.any? { _1.failed? } } }.each do |page|
|
||||||
h3 = "#{page.position} #{page.path}"
|
- current_page_pos += 1
|
||||||
- page.elements { |e| e.success_criteria.any? { _1.failed? } }.each do |element|
|
- current_element_pos = 0
|
||||||
h4 = "#{element.number} #{element.title}"
|
h3 = "2.#{current_page_pos} #{page.path}"
|
||||||
- element.success_criteria.select{ _1.failed? }.each do |sc|
|
p
|
||||||
h5 = "#{sc.number} #{sc.title}"
|
strong URL
|
||||||
|
= page.url
|
||||||
|
- page.elements.select { |e| e.success_criteria.any? { _1.failed? } }.each do |element|
|
||||||
|
- current_element_pos += 1
|
||||||
|
- current_abs_element_pos += 1
|
||||||
|
- current_sc_pos = 0
|
||||||
|
h4 = "2.#{current_page_pos}.#{current_element_pos} #{element.title}"
|
||||||
|
/h3 = "2.#{current_abs_element_pos} #{element.title}"
|
||||||
|
= safe_display(element.screenshot) { image_tag(_1.representation(resize_to_fit: [250, 250]))}
|
||||||
|
= element.description
|
||||||
|
- element.success_criteria.select(&:failed?).each do |sc|
|
||||||
|
- current_sc_pos += 1
|
||||||
|
/h4
|
||||||
|
= "2.#{current_abs_element_pos}.#{current_sc_pos} #{sc.title}"
|
||||||
|
h5 = "2.#{current_page_pos}.#{current_element_pos}.#{current_sc_pos} #{sc.title}"
|
||||||
|
p
|
||||||
|
strong Protokoll-Nummer
|
||||||
|
=< sc.number
|
||||||
- if sc.test_comment?
|
- if sc.test_comment?
|
||||||
p = sc.test_comment
|
p = sc.test_comment
|
||||||
dl
|
- safe_display(sc.quick_criterion) do
|
||||||
dt Kriterium
|
strong Kriterium
|
||||||
dd = sc.quick_criterion
|
.body_text = _1
|
||||||
dt Fail
|
- safe_display(sc.quick_fail) do
|
||||||
dd = sc.quick_fail
|
strong Quick Fail
|
||||||
dt Fix
|
.body_text = _1
|
||||||
dd = sc.quick_fix
|
- safe_display(sc.quick_fix) do
|
||||||
dt WCAG
|
strong Quick Fix
|
||||||
dd = link_to(sc.check.external_number, sc.check.external_url)
|
.body_text = _1
|
||||||
|
strong WCAG
|
||||||
|
.body_text = link_to(sc.check.external_number, sc.check.external_url)
|
||||||
|
|
||||||
h2 Anhang
|
h2 3 Anhang: Liste der zu beachtenden WCAG Regeln
|
||||||
|
- counter = 0
|
||||||
h3 Liste der zu beachtenden WCAG Regeln
|
- @failed_success_criteria.group_by(&:check).sort_by{ |c, scs| c.number }.each do |check, scs|
|
||||||
|
- counter += 1
|
||||||
- @failed_success_criteria.group_by(&:check).each do |check, scs|
|
h3 = "3.#{counter}. #{check.name_de}"
|
||||||
h4 = check.display_label
|
- safe_display(check.external_number) do
|
||||||
= check.criterion_de
|
strong WCAG Nummer
|
||||||
strong Erfolgskriterien
|
.body_text = _1
|
||||||
p = scs.map(&:number).join(", ")
|
- safe_display(check.external_url) do
|
||||||
|
strong WCAG Link
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.conformity_level) do
|
||||||
|
strong Konformität
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.conformity_notice_de) do
|
||||||
|
strong Anmerkung Konformität
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.priority) do
|
||||||
|
strong Priorität
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.criterion_de) do
|
||||||
|
strong Kriterium/Grundlage
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.exemption_details_de) do
|
||||||
|
strong Ausnahmen
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.criterion_details_de) do
|
||||||
|
strong Verstehen
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.example_de) do
|
||||||
|
strong Beispiel
|
||||||
|
.body_text = _1
|
||||||
|
- safe_display(check.annotation_de) do
|
||||||
|
strong Anmerkung
|
||||||
|
.body_text = _1
|
||||||
|
- if check.links.any?
|
||||||
|
strong Links
|
||||||
|
.body_text
|
||||||
|
- check.links.group_by(&:link_category).each do |category, links|
|
||||||
|
strong = category.t_name
|
||||||
|
ul
|
||||||
|
- links.each do |l|
|
||||||
|
li = link_to(l.text, l.url)
|
||||||
|
strong Erfolgskriterien
|
||||||
|
.body_text = scs.map(&:number).join(", ")
|
||||||
|
|
|
||||||
7
app/views/guidelines/_form.html.erb
Normal file
7
app/views/guidelines/_form.html.erb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<%= bootstrap_form_with(model: guideline) do |form| %>
|
||||||
|
<%= form.collection_select :principle_id, Principle.all.sort_by(&:id), :id, :t_name %>
|
||||||
|
<%= form.number_field :number %>
|
||||||
|
<%= form.text_field :name_de %>
|
||||||
|
<%= form.rich_text_area :description_de %>
|
||||||
|
<%= form.submit %>
|
||||||
|
<% end %>
|
||||||
15
app/views/guidelines/_guideline.html.erb
Normal file
15
app/views/guidelines/_guideline.html.erb
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div id="<%= dom_id guideline %>">
|
||||||
|
<p>
|
||||||
|
<strong>Principle:</strong>
|
||||||
|
<%= guideline.principle.t_name %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<%= guideline.description_de %>
|
||||||
|
<h2 class="mt-4">Richtlinien</h2>
|
||||||
|
<% guideline.checks.each do |check| %>
|
||||||
|
<section class="pt-3">
|
||||||
|
<h3 class="fs-5"><%= link_to check %></h3>
|
||||||
|
<%= check.t_criterion %>
|
||||||
|
</section>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
2
app/views/guidelines/_guideline.json.jbuilder
Normal file
2
app/views/guidelines/_guideline.json.jbuilder
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
json.extract! guideline, :id, :principle_id, :number, :name_de, :created_at, :updated_at
|
||||||
|
json.url guideline_url(guideline, format: :json)
|
||||||
8
app/views/guidelines/edit.html.erb
Normal file
8
app/views/guidelines/edit.html.erb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<h1><%= t("scaffold.pagetitle_edit", model: Guideline.model_name.human) %></h1>
|
||||||
|
|
||||||
|
<%= render "form", guideline: @guideline %>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_show", model: Guideline.model_name.human), @guideline %>
|
||||||
|
<%= link_to t("scaffold.link_index", model: Guideline.model_name.human(count: 2)), guidelines_path %>
|
||||||
|
</div>
|
||||||
28
app/views/guidelines/index.html.erb
Normal file
28
app/views/guidelines/index.html.erb
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<h1><%= t("scaffold.pagetitle_index", model: Guideline.model_name.human(count: 2)) %></h1>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<th><%= Guideline.human_attribute_name(:name_de) %></th>
|
||||||
|
|
||||||
|
<th><%= Guideline.human_attribute_name(:description_de) %></th>
|
||||||
|
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @guidelines.each do |guideline| %>
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<td><%= link_to(guideline, url_for(guideline)) %></td>
|
||||||
|
<td><%= link_to(guideline.description_de, url_for(guideline)) %></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_new", model: Guideline.model_name.human), new_guideline_path %>
|
||||||
|
</div>
|
||||||
1
app/views/guidelines/index.json.jbuilder
Normal file
1
app/views/guidelines/index.json.jbuilder
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
json.array! @guidelines, partial: "guidelines/guideline", as: :guideline
|
||||||
7
app/views/guidelines/new.html.erb
Normal file
7
app/views/guidelines/new.html.erb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<h1><%= t("scaffold.pagetitle_new", model: Guideline.model_name.human) %></h1>
|
||||||
|
|
||||||
|
<%= render "form", guideline: @guideline %>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_index", model: Guideline.model_name.human(count: 2)), guidelines_path %>
|
||||||
|
</div>
|
||||||
9
app/views/guidelines/show.html.erb
Normal file
9
app/views/guidelines/show.html.erb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<h1><%= @guideline %></h1>
|
||||||
|
|
||||||
|
<%= render @guideline %>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_edit", model: @guideline.model_name.human), edit_guideline_path(@guideline) %>
|
||||||
|
<%= link_to t("scaffold.link_index", model: @guideline.model_name.human(count: 2)), guidelines_path %>
|
||||||
|
<%= button_to t("scaffold.link_destroy", model: @guideline.model_name.human), @guideline, method: :delete, class: "btn btn-outline-danger" %>
|
||||||
|
</div>
|
||||||
1
app/views/guidelines/show.json.jbuilder
Normal file
1
app/views/guidelines/show.json.jbuilder
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
json.partial! "guidelines/guideline", guideline: @guideline
|
||||||
|
|
@ -1,30 +1,43 @@
|
||||||
h1 a11ydive
|
h1 Dashboard
|
||||||
h2 Dashboard
|
|
||||||
|
|
||||||
- if Report.any?
|
.row
|
||||||
h3 Zuletzt bearbeitete Prüfberichte
|
.col-md-6
|
||||||
ul
|
- if Project.current.any?
|
||||||
- Report.all.order(updated_at: :desc).limit(3).each do |r|
|
h2
|
||||||
li = link_to(r.name, r)
|
i.bi.bi-folder>
|
||||||
|
'Aktuelle Projekte
|
||||||
|
ul
|
||||||
|
- Project.current.order(updated_at: :desc).each do |p|
|
||||||
|
li = link_to(p.name, p)
|
||||||
|
|
||||||
p
|
- if Report.any?
|
||||||
i.bi.bi-journal-text
|
h2
|
||||||
=< Report.count
|
i.bi.bi-journal-text>
|
||||||
=< link_to Report.model_name.human(count: Report.count), :reports
|
'Zuletzt bearbeitete Prüfberichte
|
||||||
|
ul
|
||||||
|
- Report.all.order(updated_at: :desc).limit(3).each do |r|
|
||||||
|
li = link_to(r.name, r)
|
||||||
|
|
||||||
h3 Hotkeys
|
.col-md-6
|
||||||
p Auf der Bericht-Ausfüllen Seite können folgende Shortcuts verwendet werden:
|
h2 Browser Erweiterungen
|
||||||
dl
|
p = link_to "Language Tools KI Korrektur", "https://languagetool.org/services#browsers"
|
||||||
dt t
|
p = link_to "DeepL Firefox Extension", "https://www.deepl.com/en/firefox-extension"
|
||||||
dd Springe zum Anfang des Contents (Skip-Link, kann auf allen Seiten verwendet werden)
|
p = link_to "DeepL Chrome Extension", "https://www.deepl.com/en/chrome-extension"
|
||||||
dt a
|
p = link_to "DeepL Edge Extension", "https://www.deepl.com/en/edge-extension"
|
||||||
dd Alle auf
|
|
||||||
dt s
|
h2 Hotkeys
|
||||||
dd Alle zu
|
p Auf der Bericht-Ausfüllen Seite können folgende Shortcuts verwendet werden:
|
||||||
dt b
|
dl
|
||||||
dd Baum
|
dt t
|
||||||
dt n
|
dd Springe zum Anfang des Contents (Skip-Link, kann auf allen Seiten verwendet werden)
|
||||||
dd Notizen
|
dt a
|
||||||
dt e
|
dd Alle auf
|
||||||
dd Springe zu erstem Check
|
dt s
|
||||||
|
dd Alle zu
|
||||||
|
dt b
|
||||||
|
dd Baum
|
||||||
|
dt n
|
||||||
|
dd Notizen
|
||||||
|
dt e
|
||||||
|
dd Springe zu erstem Check
|
||||||
|
|
||||||
|
|
|
||||||
8
app/views/layouts/_toast.html.slim
Normal file
8
app/views/layouts/_toast.html.slim
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
.toast class="#{alert ? "text-bg-danger" : "text-bg-info"}" role="alert" aria-live="assertive" aria-atomic="true" data={ controller: "toast", ts: Time.now.to_f }
|
||||||
|
.toast-header
|
||||||
|
/img src="..." class="rounded me-2" alt="...">
|
||||||
|
/strong.me-auto = heading
|
||||||
|
.small.me-auto = l(Time.current.to_time)
|
||||||
|
button.btn-close type="button" data-bs-dismiss="toast" aria-label="Schliessen"
|
||||||
|
.toast-body
|
||||||
|
= content
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
doctype html
|
doctype html
|
||||||
html data-bs-theme="#{cookies[:"modeTheme"] || "light"}" data-controller="set-theme"
|
html lang=:de data-bs-theme="#{cookies[:"modeTheme"] || "light"}" data-controller="set-theme"
|
||||||
head
|
head
|
||||||
title a11ydive
|
title a11ydive
|
||||||
meta[name="viewport" content="width=device-width,initial-scale=1"]
|
meta[name="viewport" content="width=device-width,initial-scale=1"]
|
||||||
|
|
@ -16,5 +16,11 @@ html data-bs-theme="#{cookies[:"modeTheme"] || "light"}" data-controller="set-th
|
||||||
main.col.ps-md-2.pt-2
|
main.col.ps-md-2.pt-2
|
||||||
#main-content[data-controller="rich-text-link-targets"]
|
#main-content[data-controller="rich-text-link-targets"]
|
||||||
= yield
|
= yield
|
||||||
/footer.container-fluid.mt-auto.border-top
|
|
||||||
= Rails.configuration.build_version && "Version: #{Rails.configuration.build_version}"
|
.toast-container.position-fixed.top-0.end-0.p-3 id="toasts"
|
||||||
|
- if flash.alert
|
||||||
|
= render partial: "layouts/toast", locals: { content: flash.alert, alert: true }
|
||||||
|
- if flash.notice
|
||||||
|
= render partial: "layouts/toast", locals: { content: flash.notice, alert: false }
|
||||||
|
|
||||||
|
= turbo_frame_tag "modal"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
doctype html
|
doctype html
|
||||||
html data-bs-theme="light" data-controller="set-theme"
|
html
|
||||||
head
|
head
|
||||||
title a11ydive Export
|
title a11ydive Export
|
||||||
meta[name="viewport" content="width=device-width,initial-scale=1"]
|
meta[name="viewport" content="width=device-width,initial-scale=1"]
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
= csp_meta_tag
|
= csp_meta_tag
|
||||||
= stylesheet_link_tag "exports", "data-turbo-track": "reload"
|
|
||||||
= javascript_include_tag "application", "data-turbo-track": "reload", type: "module"
|
|
||||||
body
|
body
|
||||||
main#main-content
|
main.container#main-content
|
||||||
= yield
|
= yield
|
||||||
|
|
|
||||||
9
app/views/layouts/modal.html.slim
Normal file
9
app/views/layouts/modal.html.slim
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
= turbo_frame_tag "modal" do
|
||||||
|
dialog.bg-body id="modal" data={ controller: :dialog }
|
||||||
|
.float-end
|
||||||
|
form method="dialog"
|
||||||
|
button.btn.btn-outline-danger
|
||||||
|
i.bi.bi-x-lg
|
||||||
|
= yield
|
||||||
|
|
||||||
|
data-action="turbo:submit-end->turbo-modal#submitEnd"
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
= form.text_field :path
|
= form.text_field :path
|
||||||
= form.text_field :url
|
= form.text_field :url
|
||||||
= form.submit
|
= form.submit
|
||||||
= link_to("Abbrechen", report_path(@page.report), class: "btn btn-outline-secondary")
|
- unless modal?
|
||||||
|
= link_to("Abbrechen", report_path(@page.report), class: "btn btn-outline-secondary")
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,5 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= link_to("Sprinte zum ersten Element", "##{dom_id(page.elements.first)}", class: "visually-hidden", data: {controller: :hotkey, hotkey: "e", turbo: false}) if page.elements.first %>
|
<%= link_to("Springe zum ersten Element", "##{dom_id(page.elements.first)}", class: "visually-hidden", data: {controller: :hotkey, hotkey: "e", turbo: false}) if page.elements.first %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
<%= render "form", page: @page %>
|
<%= render "form", page: @page %>
|
||||||
|
|
||||||
|
<% unless modal? %>
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<%= link_to t("scaffold.link_show", model: Page.model_name.human), @page %>
|
<%= link_to t("scaffold.link_show", model: Page.model_name.human), @page %>
|
||||||
<%= link_to t("scaffold.link_index", model: Page.model_name.human(count: 2)), report_pages_path(@page.report) %>
|
<%= link_to t("scaffold.link_index", model: Page.model_name.human(count: 2)), report_pages_path(@page.report) %>
|
||||||
</div>
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ h2
|
||||||
= turbo_frame_tag(dom_id(@page, :notes)) do
|
= turbo_frame_tag(dom_id(@page, :notes)) do
|
||||||
= render partial: "pages/notes", locals: { page: @page }
|
= render partial: "pages/notes", locals: { page: @page }
|
||||||
|
|
||||||
.action-row
|
- unless modal?
|
||||||
= link_to t("scaffold.link_edit", model: @page.model_name.human), edit_page_path(@page)
|
.action-row
|
||||||
= link_to t("scaffold.link_index", model: @page.model_name.human(count: 2)), report_pages_path(@page.report)
|
= link_to t("scaffold.link_edit", model: @page.model_name.human), edit_page_path(@page)
|
||||||
= button_to t("scaffold.link_destroy", model: @page.model_name.human), @page, method: :delete, class: "btn btn-outline-danger"
|
= link_to t("scaffold.link_index", model: @page.model_name.human(count: 2)), report_pages_path(@page.report)
|
||||||
|
= button_to t("scaffold.link_destroy", model: @page.model_name.human), @page, method: :delete, class: "btn btn-outline-danger"
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,6 @@
|
||||||
= turbo_stream.update dom_id(element, :title), "#{element.page.position}.#{element.position} #{element.title}"
|
= turbo_stream.update dom_id(element, :title), "#{element.page.position}.#{element.position} #{element.title}"
|
||||||
= turbo_stream.replace dom_id(element, :page_nav_row), partial: "elements/page_nav_row", locals: { element: element, current_page: element.page == @page}
|
= turbo_stream.replace dom_id(element, :page_nav_row), partial: "elements/page_nav_row", locals: { element: element, current_page: element.page == @page}
|
||||||
- element.success_criteria.each do |sc|
|
- element.success_criteria.each do |sc|
|
||||||
= turbo_stream.update dom_id(sc, :position), "#{sc.page.position}.#{sc.element.position}.#{sc.position}"
|
= turbo_stream.update dom_id(sc, :position), "#{sc.page.position}.#{sc.element.position}.#{sc.position}"
|
||||||
|
|
||||||
|
= turbo_stream_toast("Pfad gespeichert", false)
|
||||||
5
app/views/projects/_form.html.erb
Normal file
5
app/views/projects/_form.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<%= bootstrap_form_with(model: project) do |form| %>
|
||||||
|
<%= form.text_field :name %>
|
||||||
|
<%= form.rich_text_area :details %>
|
||||||
|
<%= form.submit %>
|
||||||
|
<% end %>
|
||||||
20
app/views/projects/_project.html.slim
Normal file
20
app/views/projects/_project.html.slim
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
.project id=dom_id(project)
|
||||||
|
p
|
||||||
|
strong Name:
|
||||||
|
= project.name
|
||||||
|
p
|
||||||
|
strong Details:
|
||||||
|
= project.details
|
||||||
|
p
|
||||||
|
strong Berichte:
|
||||||
|
ul.ps-0
|
||||||
|
- project.reports.each do
|
||||||
|
li.d-flex.ps-0
|
||||||
|
=< "ID #{_1.id}: #{l(_1.created_at,format: :short)} #{_1.name}"
|
||||||
|
= link_to(_1, class: "btn btn-sm btn-link-secondary") do
|
||||||
|
i.bi.bi-folder-symlink
|
||||||
|
= button_to(project_reports_path(project), class: "btn btn-sm btn-link-secondary", params: { copy_from_id: _1.id }) do
|
||||||
|
i.bi.bi-copy
|
||||||
|
p
|
||||||
|
= link_to(new_project_report_path(project), class: "btn btn-secondary") do
|
||||||
|
i.bi.bi-plus-lg
|
||||||
2
app/views/projects/_project.json.jbuilder
Normal file
2
app/views/projects/_project.json.jbuilder
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
json.extract! project, :id, :name, :created_at, :updated_at
|
||||||
|
json.url project_url(project, format: :json)
|
||||||
8
app/views/projects/edit.html.erb
Normal file
8
app/views/projects/edit.html.erb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<h1><%= t("scaffold.pagetitle_edit", model: Project.model_name.human) %></h1>
|
||||||
|
|
||||||
|
<%= render "form", project: @project %>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_show", model: Project.model_name.human), @project %>
|
||||||
|
<%= link_to t("scaffold.link_index", model: Project.model_name.human(count: 2)), projects_path %>
|
||||||
|
</div>
|
||||||
25
app/views/projects/index.html.erb
Normal file
25
app/views/projects/index.html.erb
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<h1><%= t("scaffold.pagetitle_index", model: Project.model_name.human(count: 2)) %></h1>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><%= Project.human_attribute_name(:id) %></th>
|
||||||
|
|
||||||
|
<th><%= Project.human_attribute_name(:name) %></th>
|
||||||
|
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @projects.each do |project| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= link_to(project.id, url_for(project)) %></td>
|
||||||
|
|
||||||
|
<td><%= link_to(project.name, url_for(project)) %></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_new", model: Project.model_name.human), new_project_path %>
|
||||||
|
</div>
|
||||||
1
app/views/projects/index.json.jbuilder
Normal file
1
app/views/projects/index.json.jbuilder
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
json.array! @projects, partial: "projects/project", as: :project
|
||||||
7
app/views/projects/new.html.erb
Normal file
7
app/views/projects/new.html.erb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<h1><%= t("scaffold.pagetitle_new", model: Project.model_name.human) %></h1>
|
||||||
|
|
||||||
|
<%= render "form", project: @project %>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_index", model: Project.model_name.human(count: 2)), projects_path %>
|
||||||
|
</div>
|
||||||
9
app/views/projects/show.html.erb
Normal file
9
app/views/projects/show.html.erb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<h1><%= t("scaffold.pagetitle_show", model: @project.class.model_name.human) %></h1>
|
||||||
|
|
||||||
|
<%= render @project %>
|
||||||
|
|
||||||
|
<div class="action-row">
|
||||||
|
<%= link_to t("scaffold.link_edit", model: @project.model_name.human), edit_project_path(@project) %>
|
||||||
|
<%= link_to t("scaffold.link_index", model: @project.model_name.human(count: 2)), projects_path %>
|
||||||
|
<%= button_to t("scaffold.link_destroy", model: @project.model_name.human), @project, method: :delete, class: "btn btn-outline-danger" if @project.reports.none? %>
|
||||||
|
</div>
|
||||||
1
app/views/projects/show.json.jbuilder
Normal file
1
app/views/projects/show.json.jbuilder
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
json.partial! "projects/project", project: @project
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<%= bootstrap_form_with(model: report) do |form| %>
|
<%= bootstrap_form_with(model: report.persisted? ? report : [@project, report]) do |form| %>
|
||||||
|
<%= form.collection_select :project_id, Project.all, :id, :name, include_blank: true %>
|
||||||
<%= form.text_field :name %>
|
<%= form.text_field :name %>
|
||||||
<%= form.text_field :url %>
|
<%= form.text_field :url %>
|
||||||
<%= form.rich_text_area :comment %>
|
<%= form.rich_text_area :comment %>
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<%= link_to t("scaffold.link_show", model: Report.model_name.human), @report %>
|
<%= link_to t("scaffold.link_show", model: Report.model_name.human), @report %>
|
||||||
<%= link_to t("scaffold.link_index", model: Report.model_name.human(count: 2)), reports_path %>
|
<%= link_to t("scaffold.link_index", model: Report.model_name.human(count: 2)), project_reports_path(@report.project) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,5 @@
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<%= link_to t("scaffold.link_new", model: Report.model_name.human), new_report_path %>
|
<%= link_to t("scaffold.link_new", model: Report.model_name.human), new_project_report_path(@project) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@
|
||||||
<%= render "form", report: @report %>
|
<%= render "form", report: @report %>
|
||||||
|
|
||||||
<div class="action-row">
|
<div class="action-row">
|
||||||
<%= link_to t("scaffold.link_index", model: Report.model_name.human(count: 2)), reports_path %>
|
<%= link_to t("scaffold.link_index", model: Report.model_name.human(count: 2)), project_reports_path(@project) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,32 @@
|
||||||
|
.border-bottom.mb-3
|
||||||
|
h1
|
||||||
|
i.bi.bi-journal-text.me-2
|
||||||
|
= @report.name
|
||||||
div
|
div
|
||||||
small.float-end
|
small = "Erstellt am #{l(@report.created_at, format: :short)}, zuletzt bearbeitet am #{l(@report.updated_at, format: :short)}"
|
||||||
| Erstellt am
|
|
||||||
= l(@report.created_at, format: :short)
|
p
|
||||||
| , zuletzt bearbeitet am
|
i.bi.bi-folder
|
||||||
= l(@report.updated_at, format: :short)
|
strong< = link_to(@report.project.name, @report.project)
|
||||||
h1
|
|
||||||
i.bi.bi-journal-text.me-2
|
.smb-4.lead.mb-5
|
||||||
= @report.name
|
= @report.comment || tag.i("leer")
|
||||||
- if @report.comment
|
|
||||||
.smb-4.lead.mb-3
|
|
||||||
= @report.comment
|
|
||||||
- if @current_page
|
- if @current_page
|
||||||
h2
|
.current_page data-controller="details-list" data-target-id="element_list"
|
||||||
i.bi.bi-file-earmark-check
|
.border-bottom.mb-3.d-flex
|
||||||
=< @current_page.position
|
h2
|
||||||
=< @current_page.path
|
i.bi.bi-file-earmark-check
|
||||||
p
|
=< @current_page.position
|
||||||
'URL:
|
=< @current_page.path
|
||||||
= safe_display(@current_page.full_url) { link_to(_1, _1, target: :_blank) }
|
= page_menu(@current_page)
|
||||||
p.actions
|
p
|
||||||
.d-flex.justify-content-end data-controller="details-list" data-target-id="element_list"
|
'URL:
|
||||||
.btn-group.me-3
|
= safe_display(@current_page.full_url) { link_to(_1, _1, target: :_blank) }
|
||||||
= link_to("Alle zu [s]", "#", data: { action: "click->details-list#closeAll", controller: :hotkey, hotkey: "s" }, class: "btn btn-outline-secondary")
|
p.actions
|
||||||
= link_to("Alle auf [a]", "#", data: { action: "click->details-list#openAll", controller: :hotkey, hotkey: "a" }, class: "btn btn-outline-secondary")
|
.d-flex.justify-content-end
|
||||||
= button_to(tag.i(class: "bi bi-trash"), page_path(@current_page), method: :delete, class: "btn btn-outline-danger", form: {data: { turbo_confirm: "Bist du sicher?" }})
|
.btn-group.me-3.visually-hidden
|
||||||
|
= link_to("Alle zu [s]", "#", data: { action: "click->details-list#closeAll", controller: :hotkey, hotkey: "s" }, class: "btn btn-outline-secondary")
|
||||||
|
= link_to("Alle auf [a]", "#", data: { action: "click->details-list#openAll", controller: :hotkey, hotkey: "a" }, class: "btn btn-outline-secondary")
|
||||||
.row
|
.row
|
||||||
.col-lg-3.col-md-4.col-sm-12
|
.col-lg-3.col-md-4.col-sm-12
|
||||||
.page_nav.sticky-top
|
.page_nav.sticky-top
|
||||||
|
|
@ -40,9 +43,9 @@ h1
|
||||||
= link_to(report_export_path(@report), class: "btn btn-secondary", target: :_blank) do
|
= link_to(report_export_path(@report), class: "btn btn-secondary", target: :_blank) do
|
||||||
i.bi.bi-filetype-html
|
i.bi.bi-filetype-html
|
||||||
| Online HTML
|
| Online HTML
|
||||||
/ = link_to report_path(@report, format: :pdf), class: "btn btn-secondary", target: "_blank" do
|
= link_to report_path(@report, format: :pdf), class: "btn btn-secondary", target: "_blank" do
|
||||||
/ i.bi.bi-filetype-pdf
|
i.bi.bi-filetype-pdf
|
||||||
/ | PDF
|
| PDF
|
||||||
/ = link_to report_path(@report, format: :docx), class: "btn btn-secondary", target: "_blank" do
|
/ = link_to report_path(@report, format: :docx), class: "btn btn-secondary", target: "_blank" do
|
||||||
/ i.bi.bi-filetype-docx
|
/ i.bi.bi-filetype-docx
|
||||||
/ | DOCX
|
/ | DOCX
|
||||||
|
|
@ -60,5 +63,5 @@ h1
|
||||||
| ODT
|
| ODT
|
||||||
.action-row
|
.action-row
|
||||||
= link_to t("scaffold.link_edit", model: @report.model_name.human), edit_report_path(@report)
|
= link_to t("scaffold.link_edit", model: @report.model_name.human), edit_report_path(@report)
|
||||||
= link_to t("scaffold.link_index", model: @report.model_name.human(count: 2)), reports_path
|
= link_to t("scaffold.link_index", model: @report.model_name.human(count: 2)), project_reports_path(@report.project)
|
||||||
= button_to t("scaffold.link_destroy", model: @report.model_name.human), @report, method: :delete, class: "btn btn-outline-danger"
|
= button_to t("scaffold.link_destroy", model: @report.model_name.human), @report, method: :delete, class: "btn btn-outline-danger", data: { turbo_confirm: "Bist du sicher?"}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,21 @@
|
||||||
.content id="#{dom_id(success_criterion, :body)}"
|
.content id="#{dom_id(success_criterion, :body)}"
|
||||||
= turbo_frame_tag(dom_id(success_criterion, :frame)) do
|
= turbo_frame_tag(dom_id(success_criterion, :frame)) do
|
||||||
.row
|
.d-flex
|
||||||
.col
|
.my-3.btn-group[role="group" aria-label="Resultat"]
|
||||||
.my-3.btn-group[role="group" aria-label="Resultat"]
|
= bootstrap_form_with(model: success_criterion, data: { controller: "autosubmit" }) do |form|
|
||||||
= bootstrap_form_with(model: success_criterion, data: { controller: "autosubmit" }) do |form|
|
= form.radio_button_without_bootstrap :result, :passed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_passed)
|
||||||
= form.radio_button_without_bootstrap :result, :passed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_passed)
|
label.btn.btn-outline-success for=dom_id(success_criterion, :result_passed) Bestanden
|
||||||
label.btn.btn-outline-success for=dom_id(success_criterion, :result_passed) Bestanden
|
= form.radio_button_without_bootstrap :result, :failed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_failed)
|
||||||
= form.radio_button_without_bootstrap :result, :failed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_failed)
|
label.btn.btn-outline-danger for=dom_id(success_criterion, :result_failed) Durchgefallen
|
||||||
label.btn.btn-outline-danger for=dom_id(success_criterion, :result_failed) Durchgefallen
|
= form.radio_button_without_bootstrap :result, :not_applicable, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable)
|
||||||
= form.radio_button_without_bootstrap :result, :not_applicable, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable)
|
label.btn.btn-outline-secondary for=dom_id(success_criterion, :result_not_applicable) Nicht anwendbar
|
||||||
label.btn.btn-outline-secondary for=dom_id(success_criterion, :result_not_applicable) Nicht anwendbar
|
/= form.radio_button_without_bootstrap :result, nil, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable)
|
||||||
/= form.radio_button_without_bootstrap :result, nil, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable)
|
/label.btn.btn-outline-secondary for=dom_id(success_criterion, :nil) Reset
|
||||||
/label.btn.btn-outline-secondary for=dom_id(success_criterion, :nil) Reset
|
- unless success_criterion.test_comment.blank?
|
||||||
= button_to(tag.i(class: "bi bi-trash"), success_criterion, method: :delete, class: "btn btn-link text-danger", data: { turbo_confirm: "Bist du sicher?"})
|
= link_to(edit_comment_success_criterion_path(success_criterion), class: "btn btn-outline-warning my-3 ms-3", data: { turbo_frame: "modal" }) do
|
||||||
= success_criterion_edit_button(success_criterion, false)
|
i.bi.bi-chat>
|
||||||
|
'Kommentar bearbeiten
|
||||||
|
= success_criterion_menu(success_criterion)
|
||||||
.row
|
.row
|
||||||
.col
|
.col
|
||||||
- if success_criterion.test_comment?
|
- if success_criterion.test_comment?
|
||||||
|
|
@ -45,7 +47,7 @@
|
||||||
.text-end.fw-bold = SuccessCriterion.human_attribute_name(:quick_fix)
|
.text-end.fw-bold = SuccessCriterion.human_attribute_name(:quick_fix)
|
||||||
.col-md-8.col-lg-9
|
.col-md-8.col-lg-9
|
||||||
= success_criterion.quick_fix
|
= success_criterion.quick_fix
|
||||||
.row.mb-3
|
.row
|
||||||
.col-md-4.col-lg-3
|
.col-md-4.col-lg-3
|
||||||
.text-end.fw-bold = SuccessCriterion.human_attribute_name(:test_instructions)
|
.text-end.fw-bold = SuccessCriterion.human_attribute_name(:test_instructions)
|
||||||
.col-md-8.col-lg-9
|
.col-md-8.col-lg-9
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
<%= bootstrap_form_with(model: success_criterion.persisted? ? success_criterion : [:element, success_criterion], data: { controller: "unsaved-changes" }) do |form| %>
|
|
||||||
<%= form.text_field :title %>
|
|
||||||
<%= form.collection_select :result, SuccessCriterion.results.keys.map { [_1, t("activerecord.attributes.success_criterion.results/#{_1}")] }, :first, :second, include_blank: success_criterion.result ? "(Resultat zurücksetzen)" : "(unbeantwortet)" %>
|
|
||||||
<%= form.rich_text_area :quick_criterion %>
|
|
||||||
<%= form.rich_text_area :quick_fail %>
|
|
||||||
<%= form.rich_text_area :quick_fix %>
|
|
||||||
<%= form.rich_text_area :test_comment %>
|
|
||||||
<%= form.submit class: "btn btn-primary" %>
|
|
||||||
<%= link_to "Abbrechen", success_criterion.persisted? ? success_criterion : success_criterion.element, class: "btn btn-outline-secondary" %>
|
|
||||||
<% end %>
|
|
||||||
11
app/views/success_criteria/_form.html.slim
Normal file
11
app/views/success_criteria/_form.html.slim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
= bootstrap_form_with(model: success_criterion.persisted? ? success_criterion : [:element, success_criterion], data: { controller: "unsaved-changes" }) do |form|
|
||||||
|
= form.text_field :title
|
||||||
|
= form.collection_select :result, SuccessCriterion.results.keys.map { [_1, t("activerecord.attributes.success_criterion.results/#{_1}")] }, :first, :second, include_blank: success_criterion.result ? "(Resultat zurücksetzen)" : "(unbeantwortet)"
|
||||||
|
= form.rich_text_area :quick_criterion
|
||||||
|
= form.rich_text_area :quick_fail
|
||||||
|
= form.rich_text_area :quick_fix
|
||||||
|
= form.rich_text_area :test_comment
|
||||||
|
= form.submit class: "btn btn-primary"
|
||||||
|
- unless modal?
|
||||||
|
p Not MODAL
|
||||||
|
=< link_to "Abbrechen", success_criterion.persisted? ? success_criterion : success_criterion.element, class: "btn btn-outline-secondary"
|
||||||
|
|
@ -3,7 +3,7 @@ summary.d-flex.align-items-start id=dom_id(success_criterion, :header)
|
||||||
.content.d-flex.align-items-center.w-100
|
.content.d-flex.align-items-center.w-100
|
||||||
.result-icon.flex-shrink-0 class=[success_criterion_result_color_classes(success_criterion)]
|
.result-icon.flex-shrink-0 class=[success_criterion_result_color_classes(success_criterion)]
|
||||||
span.h1.bi class=[success_criterion_result_icon_classes(success_criterion)]
|
span.h1.bi class=[success_criterion_result_icon_classes(success_criterion)]
|
||||||
.flex-fill
|
.flex-fill.py-1
|
||||||
span id=dom_id(success_criterion, :position)
|
span id=dom_id(success_criterion, :position)
|
||||||
= success_criterion.page.position
|
= success_criterion.page.position
|
||||||
| .
|
| .
|
||||||
|
|
@ -19,4 +19,4 @@ summary.d-flex.align-items-start id=dom_id(success_criterion, :header)
|
||||||
= success_criterion_badge(success_criterion.check.external_number, extra_classes: "text-bg-info me-1")
|
= success_criterion_badge(success_criterion.check.external_number, extra_classes: "text-bg-info me-1")
|
||||||
|
|
||||||
= success_criterion_badge(success_criterion.level, extra_classes: "sc-level-#{success_criterion.level.to_s.downcase} me-1")
|
= success_criterion_badge(success_criterion.level, extra_classes: "sc-level-#{success_criterion.level.to_s.downcase} me-1")
|
||||||
i.bi.bi-grip-vertical.handle
|
i.bi.bi-grip-vertical.handle.me-1
|
||||||
|
|
|
||||||
3
app/views/success_criteria/_record_menu.html.slim
Normal file
3
app/views/success_criteria/_record_menu.html.slim
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
= dropdown_menu(klass: "mt-3 ms-auto b-0") do
|
||||||
|
= success_criterion_edit_button(@success_criterion, true)
|
||||||
|
= button_to(tag.i(class: "bi bi-trash") + " Löschen".html_safe, @success_criterion, method: :delete, class: "text-danger", data: { turbo_confirm: "Bist du sicher?"})
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
= turbo_stream.remove dom_id(@success_criterion)
|
= turbo_stream.remove dom_id(@success_criterion)
|
||||||
- @success_criterion.element.success_criteria.reject { _1 == @success_criterion }.each do |sc|
|
- @success_criterion.element.success_criteria.reject { _1 == @success_criterion }.each do |sc|
|
||||||
- Rails.logger.debug "Send to sc #{sc.id}"
|
- Rails.logger.debug "Send to sc #{sc.id}"
|
||||||
= turbo_stream.update dom_id(sc, :position), "#{sc.page.position}.#{sc.element.position}.#{sc.position}"
|
= turbo_stream.update dom_id(sc, :position), "#{sc.page.position}.#{sc.element.position}.#{sc.position}"
|
||||||
|
|
||||||
|
= turbo_stream_toast("Erfolgskriterium wurde gelöscht", true)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<h1><%= t("scaffold.pagetitle_edit", model: SuccessCriterion.model_name.human) %></h1>
|
|
||||||
|
|
||||||
<%= turbo_frame_tag(dom_id(@success_criterion, :frame)) do %>
|
|
||||||
<%= render "form", success_criterion: @success_criterion %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div class="action-row">
|
|
||||||
<%= link_to t("scaffold.link_show", model: SuccessCriterion.model_name.human), @success_criterion %>
|
|
||||||
<%= link_to t("scaffold.link_index", model: SuccessCriterion.model_name.human(count: 2)), element_success_criteria_path(@success_criterion.element) %>
|
|
||||||
</div>
|
|
||||||
7
app/views/success_criteria/edit.html.slim
Normal file
7
app/views/success_criteria/edit.html.slim
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
h2 Erfolgskriterium bearbeiten
|
||||||
|
.mb-3
|
||||||
|
= render "form", success_criterion: @success_criterion
|
||||||
|
- unless modal?
|
||||||
|
.action-row
|
||||||
|
= link_to t("scaffold.link_show", model: SuccessCriterion.model_name.human), @success_criterion
|
||||||
|
= link_to t("scaffold.link_index", model: SuccessCriterion.model_name.human(count: 2)), element_success_criteria_path(@success_criterion.element)
|
||||||
6
app/views/success_criteria/edit_comment.html.slim
Normal file
6
app/views/success_criteria/edit_comment.html.slim
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
h2 Kommentar bearbeiten
|
||||||
|
= bootstrap_form_with(model: @success_criterion.persisted? ? @success_criterion : [:element, @success_criterion], data: { controller: "unsaved-changes" }) do |form|
|
||||||
|
= form.rich_text_area :test_comment, hide_label: true
|
||||||
|
= form.submit class: "btn btn-primary"
|
||||||
|
- unless modal?
|
||||||
|
=< link_to "Abbrechen", @success_criterion.persisted? ? @success_criterion : @success_criterion.element, class: "btn btn-outline-secondary"
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
= turbo_stream.replace dom_id(@success_criterion, :body), partial: "success_criteria/body", locals: {success_criterion: @success_criterion }
|
= turbo_stream.replace dom_id(@success_criterion, :body), partial: "success_criteria/body", locals: {success_criterion: @success_criterion }
|
||||||
|
|
||||||
- @success_criterion.element.success_criteria.each do |sc|
|
- @success_criterion.element.success_criteria.each do |sc|
|
||||||
= turbo_stream.update(dom_id(sc, :position), sc.number)
|
= turbo_stream.update(dom_id(sc, :position), sc.number)
|
||||||
|
= turbo_stream_toast("Erfolgskriterium gespeichert: #{t("activerecord.attributes.success_criterion.results/#{@success_criterion.result}")}", false)
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue