generated from freelawproject/new-project-template
-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #210 from freelawproject/24-add-system-for-curators
feat(subscription): Add system for curators
- Loading branch information
Showing
32 changed files
with
4,252 additions
and
76 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
;(function () { | ||
let loadingStatesUndoQueue = [] | ||
|
||
function loadingStateContainer(target) { | ||
return htmx.closest(target, '[data-loading-states]') || document.body | ||
} | ||
|
||
function mayProcessUndoCallback(target, callback) { | ||
if (document.body.contains(target)) { | ||
callback() | ||
} | ||
} | ||
|
||
function mayProcessLoadingStateByPath(elt, requestPath) { | ||
const pathElt = htmx.closest(elt, '[data-loading-path]') | ||
if (!pathElt) { | ||
return true | ||
} | ||
|
||
return pathElt.getAttribute('data-loading-path') === requestPath | ||
} | ||
|
||
function queueLoadingState(sourceElt, targetElt, doCallback, undoCallback) { | ||
const delayElt = htmx.closest(sourceElt, '[data-loading-delay]') | ||
if (delayElt) { | ||
const delayInMilliseconds = | ||
delayElt.getAttribute('data-loading-delay') || 200 | ||
const timeout = setTimeout(() => { | ||
doCallback() | ||
|
||
loadingStatesUndoQueue.push(() => { | ||
mayProcessUndoCallback(targetElt, () => undoCallback()) | ||
}) | ||
}, delayInMilliseconds) | ||
|
||
loadingStatesUndoQueue.push(() => { | ||
mayProcessUndoCallback(targetElt, () => clearTimeout(timeout)) | ||
}) | ||
} else { | ||
doCallback() | ||
loadingStatesUndoQueue.push(() => { | ||
mayProcessUndoCallback(targetElt, () => undoCallback()) | ||
}) | ||
} | ||
} | ||
|
||
function getLoadingStateElts(loadingScope, type, path) { | ||
return Array.from(htmx.findAll(loadingScope, `[${type}]`)).filter( | ||
(elt) => mayProcessLoadingStateByPath(elt, path) | ||
) | ||
} | ||
|
||
function getLoadingTarget(elt) { | ||
if (elt.getAttribute('data-loading-target')) { | ||
return Array.from( | ||
htmx.findAll(elt.getAttribute('data-loading-target')) | ||
) | ||
} | ||
return [elt] | ||
} | ||
|
||
htmx.defineExtension('loading-states', { | ||
onEvent: function (name, evt) { | ||
if (name === 'htmx:beforeRequest') { | ||
const container = loadingStateContainer(evt.target) | ||
|
||
const loadingStateTypes = [ | ||
'data-loading', | ||
'data-loading-class', | ||
'data-loading-class-remove', | ||
'data-loading-disable', | ||
'data-loading-aria-busy', | ||
] | ||
|
||
let loadingStateEltsByType = {} | ||
|
||
loadingStateTypes.forEach((type) => { | ||
loadingStateEltsByType[type] = getLoadingStateElts( | ||
container, | ||
type, | ||
evt.detail.pathInfo.requestPath | ||
) | ||
}) | ||
|
||
loadingStateEltsByType['data-loading'].forEach((sourceElt) => { | ||
getLoadingTarget(sourceElt).forEach((targetElt) => { | ||
queueLoadingState( | ||
sourceElt, | ||
targetElt, | ||
() => | ||
(targetElt.style.display = | ||
sourceElt.getAttribute('data-loading') || | ||
'inline-block'), | ||
() => (targetElt.style.display = 'none') | ||
) | ||
}) | ||
}) | ||
|
||
loadingStateEltsByType['data-loading-class'].forEach( | ||
(sourceElt) => { | ||
const classNames = sourceElt | ||
.getAttribute('data-loading-class') | ||
.split(' ') | ||
|
||
getLoadingTarget(sourceElt).forEach((targetElt) => { | ||
queueLoadingState( | ||
sourceElt, | ||
targetElt, | ||
() => | ||
classNames.forEach((className) => | ||
targetElt.classList.add(className) | ||
), | ||
() => | ||
classNames.forEach((className) => | ||
targetElt.classList.remove(className) | ||
) | ||
) | ||
}) | ||
} | ||
) | ||
|
||
loadingStateEltsByType['data-loading-class-remove'].forEach( | ||
(sourceElt) => { | ||
const classNames = sourceElt | ||
.getAttribute('data-loading-class-remove') | ||
.split(' ') | ||
|
||
getLoadingTarget(sourceElt).forEach((targetElt) => { | ||
queueLoadingState( | ||
sourceElt, | ||
targetElt, | ||
() => | ||
classNames.forEach((className) => | ||
targetElt.classList.remove(className) | ||
), | ||
() => | ||
classNames.forEach((className) => | ||
targetElt.classList.add(className) | ||
) | ||
) | ||
}) | ||
} | ||
) | ||
|
||
loadingStateEltsByType['data-loading-disable'].forEach( | ||
(sourceElt) => { | ||
getLoadingTarget(sourceElt).forEach((targetElt) => { | ||
queueLoadingState( | ||
sourceElt, | ||
targetElt, | ||
() => (targetElt.disabled = true), | ||
() => (targetElt.disabled = false) | ||
) | ||
}) | ||
} | ||
) | ||
|
||
loadingStateEltsByType['data-loading-aria-busy'].forEach( | ||
(sourceElt) => { | ||
getLoadingTarget(sourceElt).forEach((targetElt) => { | ||
queueLoadingState( | ||
sourceElt, | ||
targetElt, | ||
() => (targetElt.setAttribute("aria-busy", "true")), | ||
() => (targetElt.removeAttribute("aria-busy")) | ||
) | ||
}) | ||
} | ||
) | ||
} | ||
|
||
if (name === 'htmx:beforeOnLoad') { | ||
while (loadingStatesUndoQueue.length > 0) { | ||
loadingStatesUndoQueue.shift()() | ||
} | ||
} | ||
}, | ||
}) | ||
})() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 5 additions & 3 deletions
8
...ets/templates/includes/yellow-button.html → ...ets/templates/includes/action-button.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,23 @@ | ||
{% comment %} | ||
This template renders a yellow button that fills the horizontal space available and | ||
This template renders a button that fills the horizontal space available and | ||
takes up to three keyword arguments described below: | ||
|
||
Parameters: | ||
link: The URL that the hyperlink points to. | ||
text: Text of the button. | ||
size: Sets the padding of the button. Possible values are: sm, md, lg | ||
color: Sets the background color of the button. Possible values are: saffron, white | ||
|
||
It's advisable to wrap this template with a div tag and use the parent element to handle | ||
the sizing and the responsive behavior. Here's an example: | ||
|
||
<div class="flex w-44 md:w-48 lg:w-52"> | ||
{% include 'includes/yellow-button.html' with link="https://free.law/contact/" text='Contact Us' size="sm" %} | ||
{% include 'includes/action-button.html' with link="https://free.law/contact/" text='Contact Us' size="sm" color='saffron'%} | ||
</div> | ||
{% endcomment %} | ||
|
||
<a href="{{link}}" | ||
class="flex justify-center w-full text-center whitespace-nowrap no-underline border border-transparent rounded-md shadow-sm text-bcb-black bg-saffron-400 hover:bg-saffron-500 {% if size == 'lg' %} p-4 {% elif size == 'md' %} p-3 {% else %} p-2 {% endif %}"> | ||
class="flex justify-center w-full text-center whitespace-nowrap no-underline border border-transparent rounded-md shadow-sm text-bcb-black {% if color == 'saffron' %} bg-saffron-400 hover:bg-saffron-500 {% else %} bg-white hover:bg-gray-100{% endif %} {% if size == 'lg' %} p-4 {% elif size == 'md' %} p-3 {% else %} p-2 {% endif %}"> | ||
{{text}} | ||
</a> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<input | ||
type="submit" | ||
value={{value}} | ||
value="{{value}}" | ||
name="submit" | ||
class="tracking-[.8px] text-center whitespace-nowrap border border-transparent rounded-md shadow-sm text-base font-medium no-underline px-4 py-2 sm:text-md cursor bg-saffron-400 hover:bg-saffron-500"/> | ||
class="tracking-[.8px] text-center whitespace-nowrap border border-transparent rounded-md shadow-sm text-base font-medium no-underline px-4 py-2 sm:text-md cursor bg-saffron-400 hover:bg-saffron-500"/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.