@antelopejs/dms 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/data/module-store/catalog.json +71 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +2 -0
- package/dist/implementations/dms/frontend-modules.js +29 -1
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +8 -0
- package/dist/implementations/dms/frontend-ready.js +34 -0
- package/dist/implementations/dms/frontend-ready.js.map +1 -0
- package/dist/implementations/dms/manifest.d.ts +1 -0
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +2 -0
- package/dist/implementations/dms/page.js +16 -0
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.js +1 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/store.d.ts +21 -0
- package/dist/routes/store.js +130 -0
- package/dist/routes/store.js.map +1 -0
- package/dist/store/activity.d.ts +2 -0
- package/dist/store/activity.js +12 -0
- package/dist/store/activity.js.map +1 -0
- package/dist/store/cache.d.ts +8 -0
- package/dist/store/cache.js +29 -0
- package/dist/store/cache.js.map +1 -0
- package/dist/store/catalog.d.ts +4 -0
- package/dist/store/catalog.js +69 -0
- package/dist/store/catalog.js.map +1 -0
- package/dist/store/compatibility.d.ts +3 -0
- package/dist/store/compatibility.js +45 -0
- package/dist/store/compatibility.js.map +1 -0
- package/dist/store/declarations.d.ts +18 -0
- package/dist/store/declarations.js +116 -0
- package/dist/store/declarations.js.map +1 -0
- package/dist/store/frontend-compatibility.d.ts +18 -0
- package/dist/store/frontend-compatibility.js +93 -0
- package/dist/store/frontend-compatibility.js.map +1 -0
- package/dist/store/interfaces.d.ts +6 -0
- package/dist/store/interfaces.js +126 -0
- package/dist/store/interfaces.js.map +1 -0
- package/dist/store/listing.d.ts +2 -0
- package/dist/store/listing.js +180 -0
- package/dist/store/listing.js.map +1 -0
- package/dist/store/operations.d.ts +8 -0
- package/dist/store/operations.js +254 -0
- package/dist/store/operations.js.map +1 -0
- package/dist/store/registry.d.ts +4 -0
- package/dist/store/registry.js +61 -0
- package/dist/store/registry.js.map +1 -0
- package/dist/store/requirements.d.ts +14 -0
- package/dist/store/requirements.js +81 -0
- package/dist/store/requirements.js.map +1 -0
- package/dist/store/runtime.d.ts +11 -0
- package/dist/store/runtime.js +78 -0
- package/dist/store/runtime.js.map +1 -0
- package/dist/store/tarball.d.ts +2 -0
- package/dist/store/tarball.js +80 -0
- package/dist/store/tarball.js.map +1 -0
- package/dist/store/types.d.ts +98 -0
- package/dist/store/types.js +3 -0
- package/dist/store/types.js.map +1 -0
- package/dist/test/unit/store/store.test.d.ts +1 -0
- package/dist/test/unit/store/store.test.js +127 -0
- package/dist/test/unit/store/store.test.js.map +1 -0
- package/dist/validation/store.schema.d.ts +39 -0
- package/dist/validation/store.schema.js +27 -0
- package/dist/validation/store.schema.js.map +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreDependencyPicker.vue +136 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +98 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +247 -29
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +19 -2
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +186 -120
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-install.ts +146 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +109 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +335 -34
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +134 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +107 -9
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +107 -9
- package/frontend-vue/package.json +3 -3
- package/frontend-vue/pnpm-lock.yaml +16 -22
- package/frontend-vue/tests/module-store-catalog.test.ts +270 -51
- package/frontend-vue/tests/top-list-card-period-badge-ssr.test.ts +212 -0
- package/package.json +1 -1
package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue
CHANGED
|
@@ -1,23 +1,175 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import ModuleTile from "./ModuleTile.vue";
|
|
3
|
+
import ModuleStoreRequirements from "./ModuleStoreRequirements.vue";
|
|
3
4
|
import {
|
|
4
|
-
MODULE_INSTALL_COMMAND,
|
|
5
|
-
moduleInstallCommand,
|
|
6
5
|
type ModuleStoreEntry,
|
|
6
|
+
type StoreAction,
|
|
7
|
+
type StoreActionBlock,
|
|
8
|
+
storeActionBlock,
|
|
9
|
+
storeActions,
|
|
10
|
+
storeTileStatus,
|
|
7
11
|
} from "../../../utils/module-store-catalog";
|
|
12
|
+
import type {
|
|
13
|
+
StoreOperationKind,
|
|
14
|
+
StoreOperationStep,
|
|
15
|
+
} from "../../../../types/module-store";
|
|
8
16
|
|
|
9
17
|
interface ModuleStoreTileProps {
|
|
10
18
|
/** The store module the tile presents. */
|
|
11
19
|
entry: ModuleStoreEntry;
|
|
20
|
+
/** Another module's operation runs: every action waits for it. */
|
|
21
|
+
isLocked?: boolean;
|
|
12
22
|
}
|
|
13
23
|
|
|
14
|
-
|
|
24
|
+
interface ModuleStoreTileEmits {
|
|
25
|
+
action: [kind: StoreOperationKind];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const props = withDefaults(defineProps<ModuleStoreTileProps>(), {
|
|
29
|
+
isLocked: false,
|
|
30
|
+
});
|
|
31
|
+
const emit = defineEmits<ModuleStoreTileEmits>();
|
|
15
32
|
const { t } = useI18n();
|
|
16
33
|
const { processI18n } = useTranslation();
|
|
17
34
|
|
|
18
35
|
const TOOLTIP_CONTENT = { side: "top", sideOffset: 6 } as const;
|
|
36
|
+
/** The steps an operation shows, in the order they run. */
|
|
37
|
+
const PROGRESS_STEPS: StoreOperationStep[] = [
|
|
38
|
+
"resolve",
|
|
39
|
+
"dependencies",
|
|
40
|
+
"unload",
|
|
41
|
+
"load",
|
|
42
|
+
"save",
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Steps an operation of this kind goes through. The file is written last:
|
|
46
|
+
* it only ever names a module that loaded.
|
|
47
|
+
*/
|
|
48
|
+
const KIND_STEPS: Record<StoreOperationKind, StoreOperationStep[]> = {
|
|
49
|
+
install: ["resolve", "dependencies", "load", "save"],
|
|
50
|
+
update: ["resolve", "unload", "load", "save"],
|
|
51
|
+
enable: ["load", "save"],
|
|
52
|
+
disable: ["unload", "save"],
|
|
53
|
+
uninstall: ["unload", "save"],
|
|
54
|
+
apply: ["load"],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const status = computed(() => storeTileStatus(props.entry));
|
|
58
|
+
const actions = computed(() => storeActions(props.entry));
|
|
59
|
+
const primary = computed<StoreAction | undefined>(() =>
|
|
60
|
+
actions.value.find((action) => !action.isMenuOnly),
|
|
61
|
+
);
|
|
62
|
+
const secondary = computed(() =>
|
|
63
|
+
actions.value
|
|
64
|
+
.filter((action) => action !== primary.value)
|
|
65
|
+
.map((action) => ({
|
|
66
|
+
label: t(`modules.store.actions.${action.labelKey}`),
|
|
67
|
+
icon: action.icon,
|
|
68
|
+
color: action.kind === "uninstall" ? ("error" as const) : undefined,
|
|
69
|
+
disabled: storeActionBlock(props.entry, action.kind) !== undefined,
|
|
70
|
+
onSelect: () => emit("action", action.kind),
|
|
71
|
+
})),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const isInstalledHere = computed(
|
|
75
|
+
() => props.entry.installedVersion !== undefined,
|
|
76
|
+
);
|
|
77
|
+
const LIST_SEPARATOR = ", ";
|
|
78
|
+
|
|
79
|
+
const BLOCK_MESSAGES: Record<StoreActionBlock, () => string> = {
|
|
80
|
+
no_release: () => t("modules.store.no_release"),
|
|
81
|
+
incompatible: () =>
|
|
82
|
+
t("modules.store.incompatible", {
|
|
83
|
+
range: props.entry.requiredInterfaceRange ?? "",
|
|
84
|
+
}),
|
|
85
|
+
frontend: () =>
|
|
86
|
+
t("modules.store.frontend_requirement.needs", {
|
|
87
|
+
range: props.entry.frontendRequirement?.range ?? "",
|
|
88
|
+
running: props.entry.frontendRequirement?.running ?? "",
|
|
89
|
+
}),
|
|
90
|
+
interfaces: () =>
|
|
91
|
+
t("modules.store.requires_first", {
|
|
92
|
+
interfaces: props.entry.missingInterfaces
|
|
93
|
+
.map((missing) => missing.interfacePackage)
|
|
94
|
+
.join(LIST_SEPARATOR),
|
|
95
|
+
}),
|
|
96
|
+
dependents: () =>
|
|
97
|
+
t("modules.store.used_by", {
|
|
98
|
+
modules: props.entry.dependents.join(LIST_SEPARATOR),
|
|
99
|
+
}),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/** Why the main action waits, when it does. */
|
|
103
|
+
const blockedReason = computed(() => {
|
|
104
|
+
if (props.isLocked) return t("modules.store.locked");
|
|
105
|
+
if (!primary.value) return undefined;
|
|
106
|
+
const block = storeActionBlock(props.entry, primary.value.kind);
|
|
107
|
+
return block ? BLOCK_MESSAGES[block]() : undefined;
|
|
108
|
+
});
|
|
109
|
+
const isBlocked = computed(() => blockedReason.value !== undefined);
|
|
110
|
+
|
|
111
|
+
const operation = computed(() => props.entry.operation);
|
|
112
|
+
/**
|
|
113
|
+
* Whether the running install loads modules for missing interfaces. Kept
|
|
114
|
+
* for the whole operation: once they run, the listing no longer misses them.
|
|
115
|
+
*/
|
|
116
|
+
const isInstallingDependencies = ref(false);
|
|
117
|
+
watch(
|
|
118
|
+
operation,
|
|
119
|
+
(running) => {
|
|
120
|
+
if (!running) {
|
|
121
|
+
isInstallingDependencies.value = false;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (
|
|
125
|
+
running.step === "dependencies" ||
|
|
126
|
+
(running.kind === "install" && props.entry.missingInterfaces.length > 0)
|
|
127
|
+
) {
|
|
128
|
+
isInstallingDependencies.value = true;
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
{ immediate: true },
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const steps = computed(() => {
|
|
135
|
+
const kind = operation.value?.kind;
|
|
136
|
+
if (!kind) return [];
|
|
137
|
+
const current = PROGRESS_STEPS.indexOf(operation.value.step);
|
|
138
|
+
const kindSteps = KIND_STEPS[kind].filter(
|
|
139
|
+
(step) => step !== "dependencies" || isInstallingDependencies.value,
|
|
140
|
+
);
|
|
141
|
+
return kindSteps.map((step) => {
|
|
142
|
+
const index = PROGRESS_STEPS.indexOf(step);
|
|
143
|
+
const state =
|
|
144
|
+
index < current ? "done" : index === current ? "running" : "todo";
|
|
145
|
+
return { step, state };
|
|
146
|
+
});
|
|
147
|
+
});
|
|
19
148
|
|
|
20
|
-
const
|
|
149
|
+
const STEP_ICONS: Record<string, string> = {
|
|
150
|
+
done: "i-ph-check-circle-fill",
|
|
151
|
+
running: "i-ph-circle-notch",
|
|
152
|
+
todo: "i-ph-circle",
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const PLAIN_VERSION = /^\d/;
|
|
156
|
+
|
|
157
|
+
/** A version as the footer shows it: `v1.2.3`, or a range as written. */
|
|
158
|
+
function formatVersion(version: string): string {
|
|
159
|
+
return PLAIN_VERSION.test(version) ? `v${version}` : version;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const versionLabel = computed(() => {
|
|
163
|
+
const { installedVersion, latestVersion, operation: running } = props.entry;
|
|
164
|
+
if (running?.targetVersion && installedVersion && running.kind === "update") {
|
|
165
|
+
return `${formatVersion(installedVersion)} → ${formatVersion(running.targetVersion)}`;
|
|
166
|
+
}
|
|
167
|
+
if (props.entry.updateAvailable && installedVersion && latestVersion) {
|
|
168
|
+
return `${formatVersion(installedVersion)} → ${formatVersion(latestVersion)}`;
|
|
169
|
+
}
|
|
170
|
+
const version = installedVersion ?? latestVersion;
|
|
171
|
+
return version ? formatVersion(version) : undefined;
|
|
172
|
+
});
|
|
21
173
|
</script>
|
|
22
174
|
|
|
23
175
|
<template>
|
|
@@ -26,49 +178,115 @@ const command = computed(() => moduleInstallCommand(props.entry));
|
|
|
26
178
|
:title="processI18n(props.entry.title)"
|
|
27
179
|
:description="processI18n(props.entry.description)"
|
|
28
180
|
:status="{
|
|
29
|
-
tone:
|
|
30
|
-
dot:
|
|
31
|
-
label: t(
|
|
181
|
+
tone: status.tone,
|
|
182
|
+
dot: status.dot,
|
|
183
|
+
label: t(`modules.store.state.${status.labelKey}`),
|
|
32
184
|
}"
|
|
185
|
+
:is-solid="isInstalledHere"
|
|
33
186
|
>
|
|
34
|
-
<!--
|
|
35
|
-
|
|
187
|
+
<!-- Running operation: its steps, the current one spinning. -->
|
|
188
|
+
<ol
|
|
189
|
+
v-if="steps.length > 0"
|
|
190
|
+
class="flex flex-col gap-1 text-xs"
|
|
191
|
+
:aria-label="t(`modules.store.progress.${operation?.kind}`)"
|
|
192
|
+
>
|
|
193
|
+
<li
|
|
194
|
+
v-for="{ step, state } in steps"
|
|
195
|
+
:key="step"
|
|
196
|
+
class="flex items-center gap-1.5"
|
|
197
|
+
:class="state === 'todo' ? 'text-dimmed' : 'text-toned'"
|
|
198
|
+
>
|
|
199
|
+
<UIcon
|
|
200
|
+
:name="STEP_ICONS[state]"
|
|
201
|
+
class="size-3.5 shrink-0"
|
|
202
|
+
:class="{
|
|
203
|
+
'animate-spin text-(--ui-primary)': state === 'running',
|
|
204
|
+
'text-(--ui-success)': state === 'done',
|
|
205
|
+
}"
|
|
206
|
+
/>
|
|
207
|
+
{{ t(`modules.store.steps.${step}`) }}
|
|
208
|
+
</li>
|
|
209
|
+
</ol>
|
|
210
|
+
|
|
211
|
+
<p
|
|
212
|
+
v-else-if="props.entry.state === 'error' && props.entry.error"
|
|
213
|
+
class="rounded-[8px] bg-(--ui-error)/8 px-2.5 py-1.5 text-xs text-(--ui-error)"
|
|
214
|
+
:title="props.entry.error"
|
|
215
|
+
>
|
|
216
|
+
<span class="line-clamp-3 break-words">{{ props.entry.error }}</span>
|
|
217
|
+
</p>
|
|
218
|
+
|
|
219
|
+
<p
|
|
220
|
+
v-else-if="props.entry.state === 'pending'"
|
|
221
|
+
class="text-xs text-(--ui-warning)"
|
|
222
|
+
>
|
|
223
|
+
{{ t("modules.store.pending_hint") }}
|
|
224
|
+
</p>
|
|
225
|
+
|
|
226
|
+
<!-- The npm package the module comes from. -->
|
|
36
227
|
<div
|
|
37
|
-
|
|
38
|
-
|
|
228
|
+
v-else
|
|
229
|
+
class="text-dimmed flex h-[30px] min-w-0 items-center rounded-[8px] border border-(--ui-border) bg-(--dms-bg-muted) px-2.5 font-mono text-[11.5px]"
|
|
230
|
+
:title="props.entry.package"
|
|
39
231
|
>
|
|
40
|
-
<span class="
|
|
41
|
-
<!-- The package name never truncates: the CLI prefix gives way first. -->
|
|
42
|
-
<span class="min-w-0 truncate">
|
|
43
|
-
<span aria-hidden="true" class="opacity-70">$</span>
|
|
44
|
-
{{ MODULE_INSTALL_COMMAND }}
|
|
45
|
-
</span>
|
|
46
|
-
<b class="text-toned shrink-0 font-semibold">
|
|
47
|
-
{{ props.entry.packageName }}
|
|
48
|
-
</b>
|
|
232
|
+
<span class="truncate">{{ props.entry.package }}</span>
|
|
49
233
|
</div>
|
|
50
234
|
|
|
235
|
+
<ModuleStoreRequirements v-if="steps.length === 0" :entry="props.entry" />
|
|
236
|
+
|
|
51
237
|
<template #footer>
|
|
52
238
|
<span class="truncate">
|
|
53
239
|
{{ processI18n(props.entry.catalogCategory) }}
|
|
54
240
|
</span>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
241
|
+
<span
|
|
242
|
+
v-if="versionLabel"
|
|
243
|
+
class="shrink-0"
|
|
244
|
+
:class="props.entry.updateAvailable ? 'text-(--ui-warning)' : ''"
|
|
245
|
+
>
|
|
246
|
+
{{ versionLabel }}
|
|
247
|
+
</span>
|
|
248
|
+
<span class="ms-auto flex shrink-0 items-center gap-1 font-sans">
|
|
58
249
|
<UTooltip
|
|
59
|
-
|
|
250
|
+
v-if="primary"
|
|
251
|
+
:text="blockedReason"
|
|
252
|
+
:disabled="!blockedReason"
|
|
60
253
|
:content="TOOLTIP_CONTENT"
|
|
61
254
|
>
|
|
255
|
+
<!-- aria-disabled rather than disabled: the button keeps its
|
|
256
|
+
tooltip, which says why it waits. -->
|
|
62
257
|
<UButton
|
|
258
|
+
size="xs"
|
|
259
|
+
:color="primary.kind === 'update' ? 'warning' : 'neutral'"
|
|
260
|
+
:variant="primary.kind === 'install' ? 'solid' : 'outline'"
|
|
261
|
+
:icon="primary.icon"
|
|
262
|
+
:label="t(`modules.store.actions.${primary.labelKey}`)"
|
|
263
|
+
:aria-disabled="isBlocked ? 'true' : undefined"
|
|
264
|
+
:class="{ 'cursor-not-allowed opacity-50': isBlocked }"
|
|
265
|
+
@click="!isBlocked && emit('action', primary.kind)"
|
|
266
|
+
/>
|
|
267
|
+
</UTooltip>
|
|
268
|
+
<UDropdownMenu
|
|
269
|
+
v-if="secondary.length > 0 && !props.isLocked"
|
|
270
|
+
:items="secondary"
|
|
271
|
+
:content="{ align: 'end' }"
|
|
272
|
+
>
|
|
273
|
+
<UButton
|
|
274
|
+
v-if="primary"
|
|
275
|
+
size="xs"
|
|
276
|
+
color="neutral"
|
|
277
|
+
variant="ghost"
|
|
278
|
+
icon="i-ph-dots-three-vertical"
|
|
279
|
+
:aria-label="t('modules.store.more_actions')"
|
|
280
|
+
/>
|
|
281
|
+
<UButton
|
|
282
|
+
v-else
|
|
63
283
|
size="xs"
|
|
64
284
|
color="neutral"
|
|
65
285
|
variant="outline"
|
|
66
|
-
icon="i-ph-
|
|
67
|
-
:label="t('modules.store.
|
|
68
|
-
aria-disabled="true"
|
|
69
|
-
@click.prevent
|
|
286
|
+
trailing-icon="i-ph-caret-down"
|
|
287
|
+
:label="t('modules.store.actions.manage')"
|
|
70
288
|
/>
|
|
71
|
-
</
|
|
289
|
+
</UDropdownMenu>
|
|
72
290
|
</span>
|
|
73
291
|
</template>
|
|
74
292
|
</ModuleTile>
|
|
@@ -23,6 +23,11 @@ interface ModuleTileProps {
|
|
|
23
23
|
status: ModuleTileStatus;
|
|
24
24
|
/** Where the tile leads; without it, the tile is a placeholder. */
|
|
25
25
|
to?: string;
|
|
26
|
+
/**
|
|
27
|
+
* A tile with no link that still stands for a module running here (one
|
|
28
|
+
* the store manages): drawn solid rather than dashed.
|
|
29
|
+
*/
|
|
30
|
+
isSolid?: boolean;
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
interface ModuleTileSlots {
|
|
@@ -36,6 +41,7 @@ interface ModuleTileSlots {
|
|
|
36
41
|
|
|
37
42
|
const props = withDefaults(defineProps<ModuleTileProps>(), {
|
|
38
43
|
to: undefined,
|
|
44
|
+
isSolid: false,
|
|
39
45
|
});
|
|
40
46
|
defineSlots<ModuleTileSlots>();
|
|
41
47
|
|
|
@@ -58,10 +64,18 @@ const theme = tv({
|
|
|
58
64
|
footer: "py-[7px]",
|
|
59
65
|
},
|
|
60
66
|
},
|
|
67
|
+
isSolid: {
|
|
68
|
+
true: {
|
|
69
|
+
root: "dms-card border-solid",
|
|
70
|
+
footer: "bg-(--dms-bg-muted) py-[7px]",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
61
73
|
},
|
|
62
74
|
});
|
|
63
75
|
|
|
64
|
-
const ui = computed(() =>
|
|
76
|
+
const ui = computed(() =>
|
|
77
|
+
theme({ isPlaceholder: !props.to, isSolid: !props.to && props.isSolid }),
|
|
78
|
+
);
|
|
65
79
|
</script>
|
|
66
80
|
|
|
67
81
|
<template>
|
|
@@ -72,7 +86,10 @@ const ui = computed(() => theme({ isPlaceholder: !props.to }));
|
|
|
72
86
|
:class="ui.root()"
|
|
73
87
|
>
|
|
74
88
|
<div class="flex items-start justify-between gap-2.5">
|
|
75
|
-
<DmsIconWell
|
|
89
|
+
<DmsIconWell
|
|
90
|
+
:icon="props.icon"
|
|
91
|
+
:tone="props.to || props.isSolid ? undefined : 'muted'"
|
|
92
|
+
/>
|
|
76
93
|
<DmsStatusPill
|
|
77
94
|
:tone="props.status.tone"
|
|
78
95
|
:dot="props.status.dot"
|