feat(editor): Make workflows, credentials, executions and new canvas usable on mobile and touch devices (#12372)

This commit is contained in:
Alex Grozav
2025-01-06 17:09:32 +02:00
committed by GitHub
parent 1b9100032f
commit 06c9473210
25 changed files with 294 additions and 29 deletions

View File

@@ -34,7 +34,11 @@ const classes = computed(() => ({
<slot name="footer" />
</div>
</div>
<div v-if="$slots.append" data-test-id="card-append" :class="$style.append">
<div
v-if="$slots.append"
data-test-id="card-append"
:class="[$style.append, 'n8n-card-append']"
>
<slot name="append" />
</div>
</div>
@@ -45,7 +49,7 @@ const classes = computed(() => ({
border-radius: var(--border-radius-large);
border: var(--border-base);
background-color: var(--color-background-xlight);
padding: var(--spacing-s);
padding: var(--card--padding, var(--spacing-s));
display: flex;
flex-direction: row;
width: 100%;
@@ -101,5 +105,6 @@ const classes = computed(() => ({
display: flex;
align-items: center;
cursor: default;
width: var(--card--append--width, unset);
}
</style>

View File

@@ -75,6 +75,38 @@ describe('useDeviceSupport()', () => {
});
});
describe('isMobileDevice', () => {
it('should be true for iOS user agent', () => {
Object.defineProperty(navigator, 'userAgent', { value: 'iphone' });
const { isMobileDevice } = useDeviceSupport();
expect(isMobileDevice).toEqual(true);
});
it('should be true for Android user agent', () => {
Object.defineProperty(navigator, 'userAgent', { value: 'android' });
const { isMobileDevice } = useDeviceSupport();
expect(isMobileDevice).toEqual(true);
});
it('should be false for non-mobile user agent', () => {
Object.defineProperty(navigator, 'userAgent', { value: 'windows' });
const { isMobileDevice } = useDeviceSupport();
expect(isMobileDevice).toEqual(false);
});
it('should be true for iPad user agent', () => {
Object.defineProperty(navigator, 'userAgent', { value: 'ipad' });
const { isMobileDevice } = useDeviceSupport();
expect(isMobileDevice).toEqual(true);
});
it('should be true for iPod user agent', () => {
Object.defineProperty(navigator, 'userAgent', { value: 'ipod' });
const { isMobileDevice } = useDeviceSupport();
expect(isMobileDevice).toEqual(true);
});
});
describe('isCtrlKeyPressed()', () => {
it('should return true for metaKey press on macOS', () => {
Object.defineProperty(navigator, 'userAgent', { value: 'macintosh' });

View File

@@ -12,12 +12,16 @@ export function useDeviceSupport() {
!window.matchMedia('(any-pointer: fine)').matches,
);
const userAgent = ref(navigator.userAgent.toLowerCase());
const isMacOs = ref(
userAgent.value.includes('macintosh') ||
const isIOs = ref(
userAgent.value.includes('iphone') ||
userAgent.value.includes('ipad') ||
userAgent.value.includes('iphone') ||
userAgent.value.includes('ipod'),
);
const isAndroidOs = ref(userAgent.value.includes('android'));
const isMacOs = ref(userAgent.value.includes('macintosh') || isIOs.value);
const isMobileDevice = ref(isIOs.value || isAndroidOs.value);
const controlKeyCode = ref(isMacOs.value ? 'Meta' : 'Control');
function isCtrlKeyPressed(e: MouseEvent | KeyboardEvent): boolean {
@@ -30,7 +34,10 @@ export function useDeviceSupport() {
return {
userAgent: userAgent.value,
isTouchDevice: isTouchDevice.value,
isAndroidOs: isAndroidOs.value,
isIOs: isIOs.value,
isMacOs: isMacOs.value,
isMobileDevice: isMobileDevice.value,
controlKeyCode: controlKeyCode.value,
isCtrlKeyPressed,
};

View File

@@ -5,6 +5,7 @@
@use './base.scss';
@use './pagination.scss';
@use './dialog.scss';
@use './display.scss';
// @use "./autocomplete.scss";
@use './dropdown.scss';
@use './dropdown-menu.scss';

View File

@@ -0,0 +1,20 @@
@use '../common/var';
@mixin breakpoint($name) {
@if map-has-key(var.$breakpoints-spec, $name) {
$query: map-get(var.$breakpoints-spec, $name);
$media-query: '';
@each $key, $value in $query {
$media-query: '#{$media-query} and (#{$key}: #{$value})';
}
$media-query: unquote(str-slice($media-query, 6)); // Remove the initial ' and '
@media screen and #{$media-query} {
@content;
}
} @else {
@error "No breakpoint named `#{$name}` found in `$breakpoints-spec`.";
}
}

View File

@@ -0,0 +1,6 @@
@forward 'breakpoints';
@forward 'button';
@forward 'config';
@forward 'function';
@forward 'mixins';
@forward 'utils';