mirror of
https://0xacab.org/sutty/sutty
synced 2024-05-14 17:30:48 +00:00
Compare commits
12 commits
6c9b9d6c25
...
9ff1ebbf48
Author | SHA1 | Date | |
---|---|---|---|
fauno | 9ff1ebbf48 | ||
044b14c355 | |||
7d5a8f8d48 | |||
14c5530b50 | |||
fauno | 0ca6689b53 | ||
11660bc688 | |||
58ee39828a | |||
9bfa2dc736 | |||
3193d72486 | |||
6ef83624a1 | |||
f00d6c6d45 | |||
9ec0dc87a9 |
106
app/javascript/controllers/dropdown_controller.js
Normal file
106
app/javascript/controllers/dropdown_controller.js
Normal file
|
@ -0,0 +1,106 @@
|
|||
import { Controller } from "stimulus";
|
||||
|
||||
// https://getbootstrap.com/docs/4.6/components/dropdowns/#single-button
|
||||
export default class extends Controller {
|
||||
static targets = ["dropdown", "button", "item"];
|
||||
|
||||
// Al iniciar el controlador
|
||||
connect() {
|
||||
// Llevar la cuenta del item con foco
|
||||
this.data.set("item", -1);
|
||||
|
||||
// Gestionar las teclas
|
||||
this.keydownEvent = this.keydown.bind(this);
|
||||
this.element.addEventListener("keydown", this.keydownEvent);
|
||||
|
||||
// Gestionar el foco
|
||||
this.focusinEvent = this.focusin.bind(this);
|
||||
}
|
||||
|
||||
// Al eliminar el controlador (al pasar a otra página)
|
||||
disconnect() {
|
||||
// Eliminar la gestión de teclas
|
||||
this.element.removeEventListener("keydown", this.keydownEvent);
|
||||
// Eliminar la gestión del foco
|
||||
document.removeEventListener("focusin", this.focusinEvent);
|
||||
}
|
||||
|
||||
// Mostrar u ocultar
|
||||
toggle(event) {
|
||||
(this.buttonTarget.ariaExpanded === "false") ? this.show() : this.hide();
|
||||
}
|
||||
|
||||
// Mostrar
|
||||
show() {
|
||||
this.buttonTarget.ariaExpanded = "true";
|
||||
this.element.classList.add("show");
|
||||
this.dropdownTarget.classList.add("show");
|
||||
|
||||
// Activar la gestión del foco
|
||||
document.addEventListener("focusin", this.focusinEvent);
|
||||
}
|
||||
|
||||
// Ocultar
|
||||
hide() {
|
||||
this.buttonTarget.ariaExpanded = "false";
|
||||
this.element.classList.remove("show");
|
||||
this.dropdownTarget.classList.remove("show");
|
||||
// Volver al inicio el foco de items
|
||||
this.data.set("item", -1);
|
||||
|
||||
// Desactivar la gestión del foco
|
||||
document.removeEventListener("focusin", this.focusinEvent);
|
||||
}
|
||||
|
||||
// Gestionar el foco
|
||||
focusin(event) {
|
||||
const item = this.itemTargets.find(x => x === event.target);
|
||||
|
||||
// Si el foco se coloca sobre elementos del controlador, no hacer
|
||||
// nada
|
||||
if (event.target === this.buttonTarget || item) {
|
||||
// Si es un item, el comportamiento de las flechas verticales y el
|
||||
// Tab tiene que ser igual
|
||||
if (item) this.data.set("item", this.itemTargets.indexOf(item));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// De lo contrario, ocultar
|
||||
this.hide();
|
||||
}
|
||||
|
||||
// Gestionar las teclas
|
||||
keydown(event) {
|
||||
const initial = parseInt(this.data.get("item"));
|
||||
let item = initial;
|
||||
|
||||
switch (event.keyCode) {
|
||||
case 27:
|
||||
// Esc cierra el menú y devuelve el foco
|
||||
this.hide();
|
||||
this.buttonTarget.focus();
|
||||
break;
|
||||
case 38:
|
||||
// Moverse hacia arriba con tope en el primer item
|
||||
if (item > -1) item--;
|
||||
|
||||
break;
|
||||
case 40:
|
||||
// Moverse hacia abajo con tope en el último ítem, si el
|
||||
// dropdown estaba cerrado, abrirlo.
|
||||
if (item === -1) this.show();
|
||||
if (item <= this.itemTargets.length) item++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Si cambió la posición del ítem, darle foco y actualizar el
|
||||
// contador.
|
||||
if (initial !== item) {
|
||||
this.itemTargets[item]?.focus();
|
||||
|
||||
this.data.set("item", item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Permite traer los cambios desde webhooks
|
||||
|
||||
# Permite traer los cambios desde el repositorio remoto
|
||||
class GitPullJob < ApplicationJob
|
||||
# @param :site [Site]
|
||||
# @param :usuarie [Usuarie]
|
||||
# @param :message [String]
|
||||
# @return [nil]
|
||||
def perform(site, usuarie)
|
||||
def perform(site, usuarie, message)
|
||||
return unless site.repository.origin
|
||||
return unless site.repository.fetch.positive?
|
||||
|
||||
site.repository.merge(usuarie)
|
||||
site.repository.fetch
|
||||
|
||||
return if site.repository.up_to_date?
|
||||
|
||||
if site.repository.fast_forward?
|
||||
site.repository.fast_forward!
|
||||
else
|
||||
site.repository.merge(usuarie, message)
|
||||
end
|
||||
|
||||
site.repository.git_lfs_checkout
|
||||
site.reindex_changes!
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -75,13 +75,18 @@ class Site
|
|||
# Forzamos el checkout para mover el HEAD al último commit y
|
||||
# escribir los cambios
|
||||
rugged.checkout 'HEAD', strategy: :force
|
||||
|
||||
git_sh("git", "lfs", "fetch", "origin", default_branch)
|
||||
# reemplaza los pointers por los archivos correspondientes
|
||||
git_sh("git", "lfs", "checkout")
|
||||
|
||||
commit
|
||||
end
|
||||
|
||||
# Trae todos los archivos desde LFS
|
||||
#
|
||||
# @return [Boolean]
|
||||
def git_lfs_checkout
|
||||
git_sh('git', 'lfs', 'fetch', 'origin', default_branch)
|
||||
git_sh('git', 'lfs', 'checkout')
|
||||
end
|
||||
|
||||
# El último commit
|
||||
#
|
||||
# @return [Rugged::Commit]
|
||||
|
@ -111,10 +116,30 @@ class Site
|
|||
walker.each.to_a
|
||||
end
|
||||
|
||||
# Hay commits sin aplicar?
|
||||
def needs_pull?
|
||||
fetch
|
||||
!commits.empty?
|
||||
# Detecta si hay que hacer un pull o no
|
||||
#
|
||||
# @return [Boolean]
|
||||
def up_to_date?
|
||||
rugged.merge_analysis(remote_head_commit).include?(:up_to_date)
|
||||
end
|
||||
|
||||
# Detecta si es posible adelantar la historia local a la remota o
|
||||
# necesitamos un merge
|
||||
#
|
||||
# @return [Boolean]
|
||||
def fast_forward?
|
||||
rugged.merge_analysis(remote_head_commit).include?(:fastforward)
|
||||
end
|
||||
|
||||
# Mueve la historia local a la remota
|
||||
#
|
||||
# @see {https://stackoverflow.com/a/27077322}
|
||||
# @return [nil]
|
||||
def fast_forward!
|
||||
rugged.checkout_tree(remote_head_commit)
|
||||
rugged.references.update(rugged.head.resolve, remote_head_commit.oid)
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
# Guarda los cambios en git
|
||||
|
|
34
app/views/components/_dropdown.haml
Normal file
34
app/views/components/_dropdown.haml
Normal file
|
@ -0,0 +1,34 @@
|
|||
-#
|
||||
@param :text [String] Contenido del botón
|
||||
@param :button_classes [Array] Clases para el botón
|
||||
@param :dropdown_classes [Array] Clases para el listado
|
||||
@yield Un bloque que renderiza components/dropdown_item
|
||||
- button_classes = local_assigns[:button_classes]&.join(' ')
|
||||
- dropdown_classes = local_assigns[:dropdown_classes]&.join(' ')
|
||||
|
||||
.btn-group{
|
||||
data: {
|
||||
controller: 'dropdown'
|
||||
}
|
||||
}
|
||||
%button.btn.dropdown-toggle{
|
||||
type: 'button',
|
||||
class: button_classes,
|
||||
data: {
|
||||
toggle: 'true',
|
||||
display: 'static',
|
||||
action: 'dropdown#toggle',
|
||||
target: 'dropdown.button'
|
||||
},
|
||||
aria: {
|
||||
expanded: 'false'
|
||||
}
|
||||
}
|
||||
= text
|
||||
.dropdown-menu{
|
||||
class: dropdown_classes,
|
||||
data: {
|
||||
target: 'dropdown.dropdown'
|
||||
}
|
||||
}
|
||||
= yield
|
4
app/views/components/_dropdown_item.haml
Normal file
4
app/views/components/_dropdown_item.haml
Normal file
|
@ -0,0 +1,4 @@
|
|||
-#
|
||||
@param :text [String] Contenido del link
|
||||
@param :path [String] Link
|
||||
= link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' }
|
|
@ -13,7 +13,7 @@
|
|||
"@rails/activestorage": "^6.1.3-1",
|
||||
"@rails/ujs": "^6.1.3-1",
|
||||
"@rails/webpacker": "5.4.4",
|
||||
"@suttyweb/editor": "^0.1.25",
|
||||
"@suttyweb/editor": "^0.1.27",
|
||||
"babel-loader": "^8.2.2",
|
||||
"chart.js": "^3.5.1",
|
||||
"chartkick": "^4.0.5",
|
||||
|
|
35
yarn.lock
35
yarn.lock
|
@ -1821,6 +1821,26 @@
|
|||
resolved "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz"
|
||||
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
|
||||
|
||||
"@floating-ui/core@^1.0.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1"
|
||||
integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==
|
||||
dependencies:
|
||||
"@floating-ui/utils" "^0.2.1"
|
||||
|
||||
"@floating-ui/dom@^1.5.1":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef"
|
||||
integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.0.0"
|
||||
"@floating-ui/utils" "^0.2.0"
|
||||
|
||||
"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2"
|
||||
integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==
|
||||
|
||||
"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
|
||||
|
@ -1955,11 +1975,13 @@
|
|||
resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz"
|
||||
integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A==
|
||||
|
||||
"@suttyweb/editor@^0.1.25":
|
||||
version "0.1.25"
|
||||
resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.25.tgz#37b38560642a49b24383473543c28be943695f9f"
|
||||
integrity sha512-fxOO9LpdntWzgNZch4cZB6QL0u+jEw0NqsNahKcGBbiJaS0GNGLRrT2LUd/Djc6O8HWkQguPLcquVT5eHq2h9g==
|
||||
"@suttyweb/editor@^0.1.27":
|
||||
version "0.1.27"
|
||||
resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.27.tgz#9415a0b767e72dbe4fbf42ce87e62fb8f5125c31"
|
||||
integrity sha512-Ts9TZtGiRIaHm+ffVBRl+/nuVcANWZNtFsrGacoajgEsagaIyA1cq8qjiNpPoM5ne9vTba3cAaLP04V/uEIhBw==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "^1.5.1"
|
||||
linkifyjs "^4.1.1"
|
||||
prosemirror-svelte-nodeview "^1.0.2"
|
||||
|
||||
"@types/caseless@*":
|
||||
|
@ -5190,6 +5212,11 @@ linkify-it@^2.0.0:
|
|||
dependencies:
|
||||
uc.micro "^1.0.1"
|
||||
|
||||
linkifyjs@^4.1.1:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.3.tgz#0edbc346428a7390a23ea2e5939f76112c9ae07f"
|
||||
integrity sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==
|
||||
|
||||
loader-runner@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz"
|
||||
|
|
Loading…
Reference in a new issue