@7365admin1/layer-common 3.2.2-staging.111 → 3.2.2-staging.112
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/assets/css/screens.css +70 -0
- package/components/AccessCardDeleteDialog.vue +41 -39
- package/components/AttendanceDetailsDialog.vue +57 -63
- package/components/ConfirmDialog.vue +14 -8
- package/components/Dialog/ReplaceAutofillPrompt.vue +19 -26
- package/components/Dialog/ReusablePrompt.vue +30 -29
- package/components/Dialog/UpdateMoreAction.vue +62 -59
- package/components/DocumentViewer.vue +29 -12
- package/components/OrgViewDialog.vue +34 -16
- package/components/PasswordConfirmation.vue +44 -26
- package/components/ScheduleTaskAreaFormDialog.vue +48 -51
- package/components/ScheduleTaskAreaUpdateMoreAction.vue +57 -62
- package/components/ServiceProviderInvitationPrompt.vue +48 -43
- package/package.json +1 -1
|
@@ -1,71 +1,67 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}}</span>
|
|
12
|
-
</v-row>
|
|
13
|
-
</template>
|
|
14
|
-
</v-toolbar>
|
|
2
|
+
<!-- The shared detail sheet several list screens open a row into. Its title
|
|
3
|
+
row and its footer were both `v-toolbar`s - fixed grey slabs that stay
|
|
4
|
+
grey on the dark theme - and the footer's action was a hardcoded
|
|
5
|
+
`color="black"` fill. -->
|
|
6
|
+
<v-card class="screen-modal" width="100%">
|
|
7
|
+
<template v-if="$slots.header">
|
|
8
|
+
<slot name="header" :title="title" :onClose="onClose" />
|
|
9
|
+
</template>
|
|
10
|
+
<v-card-title v-else class="text-capitalize">{{ title }}</v-card-title>
|
|
15
11
|
|
|
16
|
-
<v-card-text
|
|
12
|
+
<v-card-text class="screen-modal__body pb-0" :class="contentNoPadding ? 'pa-0' : ''">
|
|
17
13
|
<slot name="content" />
|
|
18
14
|
</v-card-text>
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
<!-- The design's footer strip: equal-width buttons, ghost then primary. -->
|
|
17
|
+
<div class="screen-modal__footer">
|
|
18
|
+
<v-btn
|
|
19
|
+
variant="outlined"
|
|
20
|
+
class="screen-btn-ghost"
|
|
21
|
+
@click="emit('close')"
|
|
22
|
+
>
|
|
23
|
+
Close
|
|
24
|
+
</v-btn>
|
|
25
|
+
|
|
26
|
+
<v-menu v-if="canUpdate || canDelete" contained>
|
|
27
|
+
<template #activator="{ props }">
|
|
23
28
|
<v-btn
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@click="emit('close')"
|
|
29
|
-
height="48"
|
|
29
|
+
variant="flat"
|
|
30
|
+
class="screen-btn-primary"
|
|
31
|
+
:disabled="disabled"
|
|
32
|
+
v-bind="props"
|
|
30
33
|
>
|
|
31
|
-
|
|
34
|
+
More actions
|
|
32
35
|
</v-btn>
|
|
33
|
-
</
|
|
34
|
-
|
|
35
|
-
<v-col v-if="canUpdate || canDelete" cols="6" class="pa-0" >
|
|
36
|
-
<v-menu contained>
|
|
37
|
-
<template #activator="{ props }">
|
|
38
|
-
<v-btn
|
|
39
|
-
block
|
|
40
|
-
variant="flat"
|
|
41
|
-
color="black"
|
|
42
|
-
class="text-none"
|
|
43
|
-
height="48"
|
|
44
|
-
:disabled="disabled"
|
|
45
|
-
v-bind="props"
|
|
46
|
-
tile
|
|
47
|
-
>
|
|
48
|
-
More actions
|
|
49
|
-
</v-btn>
|
|
50
|
-
</template>
|
|
36
|
+
</template>
|
|
51
37
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
38
|
+
<!-- The dropdown itself is left as Vuetify draws it: the handoff
|
|
39
|
+
specifies the PROFILE dropdown (240px, 14px radius) and mentions a
|
|
40
|
+
per-row kebab menu without giving it a shape, and this menu opens
|
|
41
|
+
on a click the harness cannot drive, so it could not be
|
|
42
|
+
render-verified either. Only the row type and the destructive ink
|
|
43
|
+
change. -->
|
|
44
|
+
<v-list class="pa-0 update-more__list">
|
|
45
|
+
<v-list-item v-if="canUpdate" @click="emit('edit')">
|
|
46
|
+
<v-list-item-title>
|
|
47
|
+
{{ editButtonLabel }}
|
|
48
|
+
</v-list-item-title>
|
|
49
|
+
</v-list-item>
|
|
58
50
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
51
|
+
<!-- `text-red` was Vuetify's fixed #f44336, the same red on both
|
|
52
|
+
themes. `text-error` is Vuetify's own class over
|
|
53
|
+
`--v-theme-error`, which IS the design's `--err`. The handoff's
|
|
54
|
+
one documented destructive treatment is the profile menu's
|
|
55
|
+
Logout row: "red Logout row (err color, err-bg hover)" - ink,
|
|
56
|
+
not a filled button - so this row follows it exactly. -->
|
|
57
|
+
<v-list-item v-if="canDelete" @click="emit('delete')" class="text-error">
|
|
58
|
+
<v-list-item-title>
|
|
59
|
+
{{ deleteButtonLabel }}
|
|
60
|
+
</v-list-item-title>
|
|
61
|
+
</v-list-item>
|
|
62
|
+
</v-list>
|
|
63
|
+
</v-menu>
|
|
64
|
+
</div>
|
|
69
65
|
</v-card>
|
|
70
66
|
</template>
|
|
71
67
|
|
|
@@ -105,4 +101,11 @@ const emit = defineEmits(["close", "edit", "delete"]);
|
|
|
105
101
|
const { canUpdate, editButtonLabel, deleteButtonLabel, title, disabled } = prop;
|
|
106
102
|
</script>
|
|
107
103
|
|
|
108
|
-
<style scoped
|
|
104
|
+
<style scoped>
|
|
105
|
+
/* `text-subtitle-2` was Vuetify's 0.875rem/500; the handoff names no type for
|
|
106
|
+
a menu row, so it takes the established cell type. */
|
|
107
|
+
.update-more__list :deep(.v-list-item-title) {
|
|
108
|
+
font-size: var(--fs-cell);
|
|
109
|
+
font-weight: var(--fw-cell);
|
|
110
|
+
}
|
|
111
|
+
</style>
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-dialog :model-value="modelValue" :max-width="fileType === 'image' ? '1200' : '900'" scrollable
|
|
3
3
|
@update:model-value="emit('update:modelValue', $event)">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
<!-- The card wears `.screen-modal` for the 16px corner, the `--card`
|
|
5
|
+
surface and the modal shadow. The `v-toolbar` header was a fixed
|
|
6
|
+
grey slab that stays grey on the dark theme; the design's modal
|
|
7
|
+
header is a title and its controls on the card's own surface over
|
|
8
|
+
a 1px `--border` rule, which is what this now draws. -->
|
|
9
|
+
<v-card class="screen-modal">
|
|
10
|
+
<v-card-title class="d-flex align-center ga-1 doc-viewer__head">
|
|
11
|
+
<span class="flex-grow-1 text-truncate">{{ fileName }}</span>
|
|
12
|
+
<!-- `.screen-modal__close` is the handoff's modal control:
|
|
13
|
+
32x32, 8px radius, borderless, `--muted` ink. The handoff
|
|
14
|
+
draws only a close in that row; a second control beside it
|
|
15
|
+
is a case it is silent on, so it takes the same shape. -->
|
|
16
|
+
<v-btn icon="mdi-open-in-new" variant="text" size="small" class="screen-modal__close"
|
|
17
|
+
@click="openInNewTab()" />
|
|
18
|
+
<v-btn icon="mdi-close" variant="text" size="small" class="screen-modal__close"
|
|
19
|
+
@click="emit('update:modelValue', false)" />
|
|
20
|
+
</v-card-title>
|
|
21
|
+
<v-card-text class="screen-modal__body pa-0"
|
|
12
22
|
:style="{ height: fileType === 'image' ? 'auto' : '75vh', 'overflow-y': fileType === 'image' ? 'auto' : 'auto' }">
|
|
13
23
|
<!-- Image Viewer -->
|
|
14
24
|
<v-img v-if="fileType === 'image'" :src="getFileUrl(fileId)" :alt="fileName" class="w-100" />
|
|
@@ -24,13 +34,12 @@
|
|
|
24
34
|
<iframe v-else :src="getFileUrl(fileId)" width="100%" height="100%" style="border: none;"
|
|
25
35
|
:title="fileName" />
|
|
26
36
|
</v-card-text>
|
|
27
|
-
<
|
|
28
|
-
<v-
|
|
29
|
-
<v-btn variant="text" class="text-none" @click="openInNewTab()">
|
|
37
|
+
<div class="screen-modal__footer">
|
|
38
|
+
<v-btn variant="outlined" class="screen-btn-ghost" @click="openInNewTab()">
|
|
30
39
|
<v-icon start>mdi-download</v-icon>
|
|
31
40
|
Open / Download
|
|
32
41
|
</v-btn>
|
|
33
|
-
</
|
|
42
|
+
</div>
|
|
34
43
|
</v-card>
|
|
35
44
|
</v-dialog>
|
|
36
45
|
</template>
|
|
@@ -73,3 +82,11 @@ function openInNewTab() {
|
|
|
73
82
|
window.open(getFileUrl(props.fileId), '_blank', 'noopener,noreferrer');
|
|
74
83
|
}
|
|
75
84
|
</script>
|
|
85
|
+
|
|
86
|
+
<style scoped>
|
|
87
|
+
/* The handoff's modal header sits over a 1px --border rule, the same rule the
|
|
88
|
+
footer strip sits under. */
|
|
89
|
+
.doc-viewer__head {
|
|
90
|
+
border-bottom: 1px solid var(--border);
|
|
91
|
+
}
|
|
92
|
+
</style>
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<!-- 760px is kept: the handoff draws exactly one modal and it is the 520px
|
|
3
|
+
Create Role form, so a multi-section detail dialog is a case it is
|
|
4
|
+
silent on, and narrowing this one would wrap fifteen label/value rows
|
|
5
|
+
rather than follow anything. What changes is the chrome. -->
|
|
2
6
|
<v-dialog v-model="model" max-width="760" scrollable>
|
|
3
|
-
<v-card
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
</v-
|
|
7
|
+
<v-card class="screen-modal">
|
|
8
|
+
<!-- Was a `v-toolbar color="grey-lighten-4"` - a literal light grey that
|
|
9
|
+
stays light grey on the dark theme, i.e. a white bar across the top
|
|
10
|
+
of a dark card. A `v-card-title` is the same row on the card's own
|
|
11
|
+
surface. -->
|
|
12
|
+
<v-card-title>View Organization Information</v-card-title>
|
|
9
13
|
|
|
10
|
-
<v-card-text class="py-4">
|
|
14
|
+
<v-card-text class="screen-modal__body py-4">
|
|
11
15
|
<template v-for="section in sections" :key="section.title">
|
|
12
|
-
<div class="
|
|
16
|
+
<div class="screen-card-title mb-2">
|
|
13
17
|
{{ section.title }}
|
|
14
18
|
</div>
|
|
15
19
|
<div
|
|
16
20
|
v-for="row in section.rows"
|
|
17
21
|
:key="row.label"
|
|
18
|
-
class="d-flex justify-space-between py-1"
|
|
22
|
+
class="d-flex justify-space-between py-1 org-view__row"
|
|
19
23
|
>
|
|
20
|
-
<span class="
|
|
21
|
-
<span class="text-
|
|
24
|
+
<span class="screen-hint">{{ row.label }}</span>
|
|
25
|
+
<span class="text-right org-view__value">
|
|
22
26
|
{{ row.value || "--" }}
|
|
23
27
|
</span>
|
|
24
28
|
</div>
|
|
@@ -26,13 +30,13 @@
|
|
|
26
30
|
</template>
|
|
27
31
|
</v-card-text>
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
<v-btn variant="
|
|
33
|
+
<!-- The design's bordered footer strip. `v-divider` plus a padded
|
|
34
|
+
actions row was the same thing drawn by hand. -->
|
|
35
|
+
<div class="screen-modal__footer">
|
|
36
|
+
<v-btn variant="outlined" class="screen-btn-ghost" @click="model = false">
|
|
33
37
|
Close
|
|
34
38
|
</v-btn>
|
|
35
|
-
</
|
|
39
|
+
</div>
|
|
36
40
|
</v-card>
|
|
37
41
|
</v-dialog>
|
|
38
42
|
</template>
|
|
@@ -116,3 +120,17 @@ const sections = computed(() => {
|
|
|
116
120
|
];
|
|
117
121
|
});
|
|
118
122
|
</script>
|
|
123
|
+
|
|
124
|
+
<style scoped>
|
|
125
|
+
/* The handoff names no type for a label/value detail row, so both take the
|
|
126
|
+
established cell type: the label on `--muted` (it was `text-medium-emphasis`,
|
|
127
|
+
Vuetify's own 60%-alpha ink) and the value on the cell weight. */
|
|
128
|
+
.org-view__row {
|
|
129
|
+
font-size: var(--fs-cell);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.org-view__value {
|
|
133
|
+
font-weight: var(--fw-cell);
|
|
134
|
+
color: var(--text);
|
|
135
|
+
}
|
|
136
|
+
</style>
|
|
@@ -1,40 +1,54 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
<!--
|
|
3
|
+
A dialog card, so it wears `.screen-modal` (16px corner, the modal shadow,
|
|
4
|
+
the `--card` surface). The two `v-toolbar`s it used to have were grey
|
|
5
|
+
slabs standing in for a title row and a footer - a `v-toolbar` keeps that
|
|
6
|
+
grey on the dark theme, so this dialog dropped a light slab onto a dark
|
|
7
|
+
card at both ends. A `v-card-title` and a `v-card-actions` are the same
|
|
8
|
+
two rows without the slab, and they follow the theme.
|
|
9
|
+
-->
|
|
10
|
+
<v-card class="screen-modal" width="100%" :disabled="loading || processingPassword" :loading="loading || processingPassword">
|
|
11
|
+
<v-card-title>{{ promptTitle }}</v-card-title>
|
|
12
|
+
|
|
13
|
+
<v-card-text class="screen-modal__body pa-5 my-5 px-7 text-center">
|
|
9
14
|
<v-row no-gutters class="w-100">
|
|
10
15
|
<v-col cols="12">
|
|
11
|
-
|
|
16
|
+
<!-- Was `:color="'gray'"`, a fixed Vuetify grey that is the
|
|
17
|
+
same grey on both themes. `--muted` is the design's
|
|
18
|
+
secondary ink and follows the theme. -->
|
|
19
|
+
<v-icon icon="mdi-lock-outline" class="text-h2 screen-lock-icon" />
|
|
12
20
|
</v-col>
|
|
13
21
|
<v-col cols="12" v-if="message" class="mt-2">
|
|
14
22
|
{{ message }}
|
|
15
23
|
</v-col>
|
|
16
24
|
<v-col cols="12" class="mt-5 text-start">
|
|
17
|
-
|
|
25
|
+
<!-- Still a `v-text-field`, not an `AppField`: it carries
|
|
26
|
+
the `:error-messages` surface that `handleConfirm`
|
|
27
|
+
writes the server's reply into, which `AppField` has
|
|
28
|
+
no equivalent for. `.filter-field` gives it the
|
|
29
|
+
design's 40px / 10px / 13.5px shape without taking
|
|
30
|
+
that away. -->
|
|
31
|
+
<v-text-field v-model="passwordInput" class="filter-field" label="Password" type="password" density="compact" :error-messages="errorMessage"></v-text-field>
|
|
18
32
|
</v-col>
|
|
19
33
|
</v-row>
|
|
20
34
|
</v-card-text>
|
|
21
35
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
<!-- The design's footer: two equal-width buttons, ghost then primary,
|
|
37
|
+
on a bordered strip. The confirming button was a hardcoded
|
|
38
|
+
`color="red"` fill; the handoff draws no destructive button, so it
|
|
39
|
+
takes the primary shape like every other modal's confirm, and the
|
|
40
|
+
destructive-variant gap is raised for a design decision rather than
|
|
41
|
+
invented here. -->
|
|
42
|
+
<div class="screen-modal__footer">
|
|
43
|
+
<v-btn class="screen-btn-ghost" variant="outlined" @click="emit('cancel')">
|
|
44
|
+
Cancel
|
|
45
|
+
</v-btn>
|
|
29
46
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</v-col>
|
|
36
|
-
</v-row>
|
|
37
|
-
</v-toolbar>
|
|
47
|
+
<v-btn class="screen-btn-primary" variant="flat" :disabled="!passwordInput"
|
|
48
|
+
@click="handleConfirm">
|
|
49
|
+
Confirm
|
|
50
|
+
</v-btn>
|
|
51
|
+
</div>
|
|
38
52
|
</v-card>
|
|
39
53
|
</template>
|
|
40
54
|
|
|
@@ -75,7 +89,7 @@ async function handleConfirm() {
|
|
|
75
89
|
const userId = currentUser.value?._id;
|
|
76
90
|
if (!userId) {
|
|
77
91
|
throw new Error('User not found. Please login again.');
|
|
78
|
-
}
|
|
92
|
+
}
|
|
79
93
|
const res = await confirmPassword({ userId, password: passwordInput.value });
|
|
80
94
|
if (res) {
|
|
81
95
|
emit('confirm');
|
|
@@ -92,4 +106,8 @@ async function handleConfirm() {
|
|
|
92
106
|
|
|
93
107
|
</script>
|
|
94
108
|
|
|
95
|
-
<style scoped
|
|
109
|
+
<style scoped>
|
|
110
|
+
.screen-lock-icon {
|
|
111
|
+
color: var(--muted);
|
|
112
|
+
}
|
|
113
|
+
</style>
|
|
@@ -2,69 +2,66 @@
|
|
|
2
2
|
<v-dialog
|
|
3
3
|
:model-value="modelValue"
|
|
4
4
|
@update:model-value="(v) => emit('update:modelValue', v)"
|
|
5
|
-
max-width="
|
|
5
|
+
max-width="520"
|
|
6
6
|
>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</v-toolbar>
|
|
7
|
+
<!-- 520px is the handoff's `--modal-w`, and the card wears `.screen-modal`
|
|
8
|
+
for the 16px corner, the `--card` surface and the modal shadow. The
|
|
9
|
+
two `v-toolbar`s standing in for the title row and the footer were
|
|
10
|
+
fixed grey slabs that stay grey on the dark theme, and the Create
|
|
11
|
+
button was a hardcoded `color="black"` fill on a `rounded-0` square. -->
|
|
12
|
+
<v-card class="screen-modal">
|
|
13
|
+
<template v-if="$slots.header">
|
|
14
|
+
<slot
|
|
15
|
+
name="header"
|
|
16
|
+
:title="
|
|
17
|
+
mode === 'edit' ? `Edit ${entityType}` : `Add New ${entityType}`
|
|
18
|
+
"
|
|
19
|
+
:onClose="onClose"
|
|
20
|
+
/>
|
|
21
|
+
</template>
|
|
22
|
+
<v-card-title v-else class="text-capitalize">{{
|
|
23
|
+
mode === "edit" ? `Edit ${entityType}` : `Add New ${entityType}`
|
|
24
|
+
}}</v-card-title>
|
|
26
25
|
|
|
27
|
-
<v-card-text>
|
|
26
|
+
<v-card-text class="screen-modal__body">
|
|
28
27
|
<v-form ref="formRef" v-model="valid">
|
|
29
28
|
<v-row>
|
|
30
29
|
<v-col cols="12">
|
|
31
30
|
<InputLabel for="name" :title="label" required />
|
|
32
|
-
|
|
31
|
+
<!-- Still a `v-text-field`: Submit is gated on `valid`, which
|
|
32
|
+
only exists because this `:rules` runs. `.filter-field` gives
|
|
33
|
+
it the design's 40px / 10px / 13.5px shape without taking the
|
|
34
|
+
validation away. -->
|
|
35
|
+
<v-text-field
|
|
36
|
+
v-model="nameValue"
|
|
37
|
+
class="filter-field"
|
|
38
|
+
:rules="[requiredRule]"
|
|
39
|
+
/>
|
|
33
40
|
</v-col>
|
|
34
41
|
</v-row>
|
|
35
42
|
</v-form>
|
|
36
43
|
</v-card-text>
|
|
37
44
|
|
|
38
|
-
<
|
|
39
|
-
<v-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@click="close"
|
|
47
|
-
height="48"
|
|
48
|
-
>
|
|
49
|
-
Cancel
|
|
50
|
-
</v-btn>
|
|
51
|
-
</v-col>
|
|
45
|
+
<div class="screen-modal__footer">
|
|
46
|
+
<v-btn
|
|
47
|
+
variant="outlined"
|
|
48
|
+
class="screen-btn-ghost"
|
|
49
|
+
@click="close"
|
|
50
|
+
>
|
|
51
|
+
Cancel
|
|
52
|
+
</v-btn>
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
</v-btn>
|
|
65
|
-
</v-col>
|
|
66
|
-
</v-row>
|
|
67
|
-
</v-toolbar>
|
|
54
|
+
<!-- Kept a `v-btn`: `loading` is the only in-flight signal this form
|
|
55
|
+
has, and `AppButton` has no equivalent. -->
|
|
56
|
+
<v-btn
|
|
57
|
+
variant="flat"
|
|
58
|
+
class="screen-btn-primary"
|
|
59
|
+
:loading="submitting"
|
|
60
|
+
@click="submit"
|
|
61
|
+
>
|
|
62
|
+
{{ mode === "edit" ? "Save" : "Create" }}
|
|
63
|
+
</v-btn>
|
|
64
|
+
</div>
|
|
68
65
|
</v-card>
|
|
69
66
|
</v-dialog>
|
|
70
67
|
</template>
|
|
@@ -1,74 +1,62 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}}</span>
|
|
12
|
-
</v-row>
|
|
13
|
-
</template>
|
|
14
|
-
</v-toolbar>
|
|
2
|
+
<!-- The schedule-area copy of `Dialog/UpdateMoreAction`, converted the same
|
|
3
|
+
way: two `v-toolbar`s (fixed grey slabs that stay grey on the dark
|
|
4
|
+
theme) for the title row and the footer, and a hardcoded `color="black"`
|
|
5
|
+
fill on a square 48px tile. -->
|
|
6
|
+
<v-card class="screen-modal" width="100%">
|
|
7
|
+
<template v-if="$slots.header">
|
|
8
|
+
<slot name="header" :title="title" :onClose="onClose" />
|
|
9
|
+
</template>
|
|
10
|
+
<v-card-title v-else class="text-capitalize">{{ title }}</v-card-title>
|
|
15
11
|
|
|
16
|
-
<v-card-text
|
|
12
|
+
<v-card-text class="screen-modal__body pb-0">
|
|
17
13
|
<slot name="content" />
|
|
18
14
|
</v-card-text>
|
|
19
15
|
|
|
20
|
-
<
|
|
21
|
-
<v-
|
|
22
|
-
|
|
16
|
+
<div class="screen-modal__footer">
|
|
17
|
+
<v-btn
|
|
18
|
+
variant="outlined"
|
|
19
|
+
class="screen-btn-ghost"
|
|
20
|
+
@click="emit('close')"
|
|
21
|
+
>
|
|
22
|
+
Close
|
|
23
|
+
</v-btn>
|
|
24
|
+
|
|
25
|
+
<v-menu>
|
|
26
|
+
<template #activator="{ props }">
|
|
23
27
|
<v-btn
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
size="large"
|
|
28
|
-
@click="emit('close')"
|
|
29
|
-
height="48"
|
|
28
|
+
variant="flat"
|
|
29
|
+
class="screen-btn-primary"
|
|
30
|
+
v-bind="props"
|
|
30
31
|
>
|
|
31
|
-
|
|
32
|
+
More actions
|
|
32
33
|
</v-btn>
|
|
33
|
-
</
|
|
34
|
-
|
|
35
|
-
<v-col cols="6" class="pa-0">
|
|
36
|
-
<v-menu>
|
|
37
|
-
<template #activator="{ props }">
|
|
38
|
-
<v-btn
|
|
39
|
-
block
|
|
40
|
-
variant="flat"
|
|
41
|
-
color="black"
|
|
42
|
-
class="text-none"
|
|
43
|
-
height="48"
|
|
44
|
-
v-bind="props"
|
|
45
|
-
tile
|
|
46
|
-
>
|
|
47
|
-
More actions
|
|
48
|
-
</v-btn>
|
|
49
|
-
</template>
|
|
34
|
+
</template>
|
|
50
35
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
36
|
+
<!-- Dropdown shape left as Vuetify draws it - the handoff specifies
|
|
37
|
+
the profile dropdown only. `text-red` (Vuetify's fixed #f44336,
|
|
38
|
+
the same red on both themes) becomes `text-error`, which is
|
|
39
|
+
`--v-theme-error`, i.e. the design's `--err`, matching the
|
|
40
|
+
handoff's "red Logout row (err color, err-bg hover)". -->
|
|
41
|
+
<v-list class="pa-0 area-more__list">
|
|
42
|
+
<v-list-item v-if="canUpdate" @click="emit('edit')">
|
|
43
|
+
<v-list-item-title>
|
|
44
|
+
{{ editButtonLabel }}
|
|
45
|
+
</v-list-item-title>
|
|
46
|
+
</v-list-item>
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</v-row>
|
|
71
|
-
</v-toolbar>
|
|
48
|
+
<v-list-item
|
|
49
|
+
v-if="canDelete"
|
|
50
|
+
@click="emit('delete')"
|
|
51
|
+
class="text-error"
|
|
52
|
+
>
|
|
53
|
+
<v-list-item-title>
|
|
54
|
+
{{ deleteButtonLabel }}
|
|
55
|
+
</v-list-item-title>
|
|
56
|
+
</v-list-item>
|
|
57
|
+
</v-list>
|
|
58
|
+
</v-menu>
|
|
59
|
+
</div>
|
|
72
60
|
</v-card>
|
|
73
61
|
</template>
|
|
74
62
|
|
|
@@ -106,4 +94,11 @@ const {
|
|
|
106
94
|
} = prop;
|
|
107
95
|
</script>
|
|
108
96
|
|
|
109
|
-
<style scoped
|
|
97
|
+
<style scoped>
|
|
98
|
+
/* `text-subtitle-2` was Vuetify's 0.875rem/500; the handoff names no type for
|
|
99
|
+
a menu row, so it takes the established cell type. */
|
|
100
|
+
.area-more__list :deep(.v-list-item-title) {
|
|
101
|
+
font-size: var(--fs-cell);
|
|
102
|
+
font-weight: var(--fw-cell);
|
|
103
|
+
}
|
|
104
|
+
</style>
|