Skip to content

Commit caa8232

Browse files
authored
Merge pull request #6670 from FlowFuse/immersive-editor-home-icon
Ensure consistent Open Editor behavior — always default to immersive experience
2 parents c909cfa + 5e4ae04 commit caa8232

22 files changed

Lines changed: 512 additions & 185 deletions

File tree

frontend/src/components/TextCopier.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<template>
22
<span class="ff-text-copier">
3-
<span v-if="showText" @click="copyPath">
3+
<span v-if="showText" @click.stop="copyPath">
44
<slot name="default">
55
<span class="text">{{ text }}</span>
66
</slot>
77
</span>
8-
<button v-if="hasText" class="ff-icon-button" @click="copyPath">
8+
<button v-if="hasText" class="ff-icon-button" @click.stop="copyPath">
99
<DuplicateIcon v-if="!copied" class="ff-icon" />
1010
<CheckIcon v-else class="ff-icon ff-icon-check" />
1111
</button>
@@ -114,15 +114,15 @@ export default {
114114
border-radius: 4px;
115115
cursor: pointer;
116116
transition: all 0.2s ease;
117-
color: $ff-grey-600;
117+
color: $ff-color--action;
118118
119119
&:hover {
120-
color: $ff-indigo-600;
121-
background-color: $ff-indigo-50;
120+
color: $ff-white;
121+
background-color: $ff-color--highlight;
122122
}
123123
124124
&:active {
125-
background-color: $ff-indigo-100;
125+
background-color: $ff-color--highlight;
126126
}
127127
128128
.ff-icon {

frontend/src/components/instance/ActionButton.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="action-button" data-el="action-button">
33
<DropdownMenu
44
v-if="hasPermission('project:change-status', { application: instance.application })"
5-
buttonClass="ff-btn ff-btn--primary ff-btn-icon"
5+
:buttonClass="`ff-btn ${isEditorUsable ? 'ff-btn--secondary' : 'ff-btn--primary'} ff-btn-icon`"
66
:options="actionsDropdownOptions"
77
>
88
<CogIcon class="ff-btn--icon ff-btn--icon-left" />
@@ -84,6 +84,10 @@ export default {
8484
},
8585
instanceRunning () {
8686
return this.instance?.meta?.state === 'running'
87+
},
88+
isEditorUsable () {
89+
const isHA = this.instance?.ha?.replicas !== undefined
90+
return this.instanceRunning && !isHA && !this.instance?.settings?.disableEditor
8791
}
8892
8993
},

frontend/src/composables/NavigationHelper.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,21 @@ export function useNavigationHelper () {
2020
}
2121
}
2222

23-
const navigateTo = (to, $event = null) => {
23+
const navigateTo = (to, $event = null, { target = '_blank' } = {}) => {
2424
const internalHref = _router.resolve(to).href
2525
const isMiddleButtonClick = $event?.button === 1
2626
const newTabKeyCombination = $event && ($event?.ctrlKey || $event.metaKey || isMiddleButtonClick)
2727
const isExternalLink = _isExternalLink(to)
2828

2929
switch (true) {
3030
case isExternalLink && newTabKeyCombination:
31-
return openInANewTab(to)
31+
return openInANewTab(to, target)
3232

3333
case isExternalLink:
3434
return navigateToExternal(to)
3535

3636
case newTabKeyCombination:
37-
return openInANewTab(internalHref)
37+
return openInANewTab(internalHref, target)
3838

3939
default:
4040
return _router.push(to)

frontend/src/pages/admin/Template/sections/Environment.vue

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,26 @@
5353
<template #rows>
5454
<ff-data-table-row v-for="(item) in filteredRows" :key="item.index" :data-row="'row-' + item.name">
5555
<td class="ff-data-table--cell !pl-1 !pr-0 !py-1 border min-w-max max-w-sm align-top">
56-
<FormRow
57-
v-model="item.name"
58-
v-ff-tooltip:left="'Cannot be renamed'"
59-
class="font-mono"
60-
:containerClass="'w-full' + (!readOnly && (editTemplate || item.policy === undefined)) ? ' env-cell-uneditable':''"
61-
:inputClass="item.deprecated ? 'w-full text-yellow-700 italic' : 'w-full'"
62-
:error="errors[item.index] ? errors[item.index].error : null"
63-
:disabled="isDisabledName(item)"
64-
value-empty-text=""
56+
<template v-if="(!readOnly && (editTemplate || item.policy === undefined))">
57+
<FormRow
58+
v-model="item.name"
59+
v-ff-tooltip:left="'Cannot be renamed'"
60+
class="font-mono"
61+
:containerClass="'w-full env-cell-uneditable'"
62+
:inputClass="item.deprecated ? 'w-full text-yellow-700 italic' : 'w-full'"
63+
:error="errors[item.index] ? errors[item.index].error : null"
64+
:disabled="isDisabledName(item)"
65+
value-empty-text=""
66+
data-el="var-name"
67+
type="text"
68+
/>
69+
</template>
70+
<TextCopier
71+
v-else
72+
:text="item.name"
73+
class="font-mono env-cell-uneditable w-full pl-2"
74+
:class="item.deprecated ? 'text-yellow-700 italic' : ''"
6575
data-el="var-name"
66-
:type="(!readOnly && (editTemplate || item.policy === undefined)) ? 'text' : 'uneditable'"
6776
/>
6877
</td>
6978
<td class="ff-data-table--cell !p-1 border w-3/5 max-w-xl" :class="{'align-middle':item.encrypted, 'align-top': !item.hidden}">
@@ -162,6 +171,7 @@ import { DocumentDownloadIcon, ExclamationIcon, EyeIcon, EyeOffIcon, Information
162171
163172
import FormHeading from '../../../../components/FormHeading.vue'
164173
import FormRow from '../../../../components/FormRow.vue'
174+
import TextCopier from '../../../../components/TextCopier.vue'
165175
import Alerts from '../../../../services/alerts.js'
166176
import ChangeIndicator from '../components/ChangeIndicator.vue'
167177
import LockSetting from '../components/LockSetting.vue'
@@ -181,7 +191,8 @@ export default {
181191
ExclamationIcon,
182192
InformationCircleIcon,
183193
EyeIcon,
184-
EyeOffIcon
194+
EyeOffIcon,
195+
TextCopier
185196
},
186197
props: {
187198
editTemplate: {

frontend/src/pages/application/Overview.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export default {
169169
...mapGetters('account', ['featuresCheck']),
170170
cloudColumns () {
171171
return [
172-
{ label: 'Name', class: ['w-1/2'], component: { is: markRaw(DeploymentName) } },
172+
{ label: 'Name', class: ['w-1/2'], component: { is: markRaw(DeploymentName), map: { url: 'url' } } },
173173
{
174174
label: 'Instance Status',
175175
class: ['w-1/5'],

frontend/src/pages/application/components/cells/DeploymentName.vue

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,52 @@
33
class="flex items-center gap-2"
44
>
55
<IconNodeRedSolid class="ff-icon ff-icon-lg text-red-800" />
6-
<div class="flex flex-col space-y-1">
7-
{{ name }}
6+
<div class="flex flex-col">
7+
<span>{{ name }}</span>
8+
<TextCopier
9+
v-if="url && copyable"
10+
:text="url"
11+
:show-text="true"
12+
class="deployment-name__url text-xs text-gray-400"
13+
/>
14+
<span v-else-if="url" class="text-xs text-gray-400">{{ url }}</span>
815
</div>
916
</span>
1017
</template>
1118

1219
<script>
20+
import TextCopier from '../../../../components/TextCopier.vue'
1321
import IconNodeRedSolid from '../../../../components/icons/NodeRedSolid.js'
1422
1523
export default {
1624
name: 'DeploymentName',
17-
components: { IconNodeRedSolid },
25+
components: { IconNodeRedSolid, TextCopier },
1826
inheritAttrs: false,
1927
props: {
2028
name: {
2129
required: true,
2230
type: String
31+
},
32+
url: {
33+
type: String,
34+
default: ''
35+
},
36+
copyable: {
37+
type: Boolean,
38+
default: true
2339
}
2440
}
2541
}
2642
</script>
43+
44+
<style scoped lang="scss">
45+
.deployment-name__url {
46+
:deep(.ff-icon) {
47+
width: 14px;
48+
height: 14px;
49+
}
50+
:deep(.ff-icon-button) {
51+
background: transparent;
52+
}
53+
}
54+
</style>

frontend/src/pages/device/Editor/index.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
title="Back to remote instance overview"
2626
:to="{ name: 'device-overview', params: {id: device.id} }"
2727
>
28-
<ArrowLeftIcon class="ff-btn--icon" />
28+
<HomeIcon class="ff-btn--icon" style="width: 18px; height: 18px;" />
2929
</router-link>
3030
</div>
3131
<ff-tabs :tabs="navigation" class="tabs" />
@@ -54,7 +54,7 @@
5454

5555
<script>
5656
57-
import { ArrowLeftIcon, XIcon } from '@heroicons/vue/solid/index.js'
57+
import { HomeIcon, XIcon } from '@heroicons/vue/solid/index.js'
5858
import semver from 'semver'
5959
import { mapActions, mapGetters, mapState } from 'vuex'
6060
@@ -77,7 +77,7 @@ export default {
7777
name: 'DeviceEditor',
7878
components: {
7979
XIcon,
80-
ArrowLeftIcon,
80+
HomeIcon,
8181
FfPage,
8282
DrawerTrigger,
8383
ResizeBar,

frontend/src/pages/instance/Editor/index.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<div class="header">
2727
<div class="logo">
2828
<router-link title="Back to instance overview" :to="{ name: 'instance-overview', params: {id: instance.id} }">
29-
<ArrowLeftIcon class="ff-btn--icon" />
29+
<HomeIcon class="ff-btn--icon" style="width: 18px; height: 18px;" />
3030
</router-link>
3131
</div>
3232
<ff-tabs :tabs="navigation" class="tabs" />
@@ -69,7 +69,7 @@
6969
</template>
7070

7171
<script>
72-
import { ArrowLeftIcon, XIcon } from '@heroicons/vue/solid'
72+
import { HomeIcon, XIcon } from '@heroicons/vue/solid'
7373
import { mapActions, mapGetters } from 'vuex'
7474
7575
import InstanceStatusPolling from '../../../components/InstanceStatusPolling.vue'
@@ -98,7 +98,7 @@ const DRAWER_MAX_WIDTH_RATIO = 0.9 // Maximum drawer width as percentage of view
9898
export default {
9999
name: 'InstanceEditor',
100100
components: {
101-
ArrowLeftIcon,
101+
HomeIcon,
102102
ConfirmInstanceDeleteDialog,
103103
InstanceActionsButton,
104104
DashboardLink,

0 commit comments

Comments
 (0)