- Rebuild the widget server-backed: it renders only when GET state allows (logged-in FE user of the configured group), so the script tag is safe on public pages; form with mini rich text (bold/italic/ list), file attachment chips and Ctrl+V image paste - a paste lazily creates the draft feedback, uploads and inserts the image inline - Note pad badge mirrors the server item count; the pad button links to the overview page via new extension setting overviewPid, exposed as overviewUrl in GET state (slug lookup) - Embed /fileadmin images of notes into the feedback mail as CID parts: relative srcs are dead in mail clients and dev sits behind basic auth; attachment links stay absolute URLs - public/widget-test.html: dev test page, doubles as the reference implementation of the React login flow (fetch felogin JSON form incl. __RequestToken, urlencoded POST to /_json + form.action) - Docs section 5x (fe_comment v2 incl. CSRF login lesson, templateRootPaths.10 collision, cache:flush before extension:setup)
166 lines
3.9 KiB
CSS
166 lines
3.9 KiB
CSS
/* EXT:fe_comment v2 widget — isolated styles, .evofc-prefixed, high z-index. */
|
|
|
|
.evofc {
|
|
position: fixed;
|
|
right: 0;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
z-index: 2147483000;
|
|
font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
|
|
font-size: 14px;
|
|
line-height: 1.45;
|
|
color: #1c2430;
|
|
}
|
|
|
|
.evofc-toggle {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 44px;
|
|
height: 44px;
|
|
border: 0;
|
|
border-radius: 8px 0 0 8px;
|
|
background: #1f6feb;
|
|
color: #fff;
|
|
cursor: pointer;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, .25);
|
|
}
|
|
.evofc-toggle:hover { background: #1a5fd0; }
|
|
|
|
.evofc-badge {
|
|
position: absolute;
|
|
top: -6px;
|
|
left: -6px;
|
|
min-width: 18px;
|
|
height: 18px;
|
|
padding: 0 4px;
|
|
border-radius: 9px;
|
|
background: #d9463e;
|
|
color: #fff;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.evofc-panel {
|
|
position: absolute;
|
|
right: 52px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 340px;
|
|
max-width: calc(100vw - 70px);
|
|
max-height: 80vh;
|
|
overflow: auto;
|
|
background: #fff;
|
|
border: 1px solid #d5dbe3;
|
|
border-radius: 10px;
|
|
box-shadow: 0 8px 30px rgba(0, 0, 0, .22);
|
|
padding: 14px;
|
|
}
|
|
|
|
.evofc-title { font-weight: 700; margin-bottom: 10px; }
|
|
.evofc-label { display: block; font-size: 12px; color: #5a6572; margin: 8px 0 2px; }
|
|
|
|
.evofc-url {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
border: 1px solid #c9d1da;
|
|
border-radius: 6px;
|
|
padding: 6px 8px;
|
|
font: inherit;
|
|
background: #f3f5f7;
|
|
color: #5a6572;
|
|
}
|
|
|
|
/* Mini toolbar + rich-text area */
|
|
.evofc-toolbar { display: flex; gap: 4px; margin-bottom: 4px; }
|
|
.evofc-tool {
|
|
min-width: 28px;
|
|
height: 26px;
|
|
border: 1px solid #c9d1da;
|
|
border-radius: 5px;
|
|
background: #f6f8fa;
|
|
color: #1c2430;
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
padding: 0 6px;
|
|
}
|
|
.evofc-tool:hover { background: #eef1f4; }
|
|
|
|
.evofc-rte {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
min-height: 96px;
|
|
max-height: 260px;
|
|
overflow: auto;
|
|
border: 1px solid #c9d1da;
|
|
border-radius: 6px;
|
|
padding: 6px 8px;
|
|
background: #fff;
|
|
outline: none;
|
|
}
|
|
.evofc-rte:focus { border-color: #1f6feb; }
|
|
.evofc-rte:empty::before {
|
|
content: attr(data-placeholder);
|
|
color: #9aa4af;
|
|
pointer-events: none;
|
|
}
|
|
.evofc-rte img { max-width: 100%; height: auto; border-radius: 4px; }
|
|
.evofc-rte ul { margin: 4px 0; padding-left: 20px; }
|
|
|
|
/* Attachment chips */
|
|
.evofc-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
|
|
.evofc-chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
max-width: 100%;
|
|
border: 1px solid #e2e7ec;
|
|
border-radius: 12px;
|
|
background: #f6f8fa;
|
|
padding: 2px 6px 2px 10px;
|
|
font-size: 12px;
|
|
}
|
|
.evofc-chip-name {
|
|
max-width: 200px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.evofc-row { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
|
|
|
|
.evofc-button {
|
|
border: 1px solid #c9d1da;
|
|
border-radius: 6px;
|
|
background: #f6f8fa;
|
|
color: #1c2430;
|
|
padding: 7px 12px;
|
|
font: inherit;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
}
|
|
.evofc-button:hover { background: #eef1f4; }
|
|
.evofc-button:disabled { opacity: .6; cursor: default; }
|
|
.evofc-primary { background: #1f6feb; border-color: #1f6feb; color: #fff; }
|
|
.evofc-primary:hover { background: #1a5fd0; }
|
|
.evofc-primary:disabled { opacity: .6; cursor: default; }
|
|
|
|
.evofc-hint { color: #2f9e44; font-size: 12px; }
|
|
.evofc-footer { margin-top: 10px; }
|
|
.evofc-status { margin: 8px 0 0; font-size: 13px; font-weight: 600; color: #d9463e; }
|
|
.evofc-status:empty { display: none; }
|
|
|
|
.evofc-remove {
|
|
border: 0;
|
|
background: none;
|
|
color: #d9463e;
|
|
font-size: 16px;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
padding: 2px 4px;
|
|
}
|